Angular directive to display Flash via the <object> tag causes Flash to attempt to load {{expression}}

I have an AngularJS directive:

myApp.directive('movie', function(){ return { restrict: 'E', replace: true, scope: { product:'=', codebase: '@' }, template: '<object style="width:550px;height:320px;" name="movie" id="movie" codebase="{{codebase}}"' + ' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" tabindex="-1">' + '<param value="{{product.flashURL}}" name="movie">' + '<param value="true" name="play">' + '<param value="true" name="menu">' + '<param value="transparent" name="wmode">' + '<param value="noscale" name="scale">' + '<embed wmode="transparent" style="width:550px;height:320px;" src="{{product.flashURL}}" scale="noscale"' + ' pluginspage="http://www.macromedia.com/go/getflashplayer" play="true" name="movieEmbed" menu="true" id="movieEmbed">' + '</object>' };}); 

It is used as follows:

 <movie product="productInScope" codebase="http://flashcodebase..." /> 

I made this directive to fix the problem that I encountered by simply including this HTML in the view, which is this: the moment the tag object is rendered, Flash tries to load the movie at the URL "{{product. FlashURL}} " This clearly fails, and by the time Angular comes close to interpolating the expression, it's too late.

Unfortunately, restructuring it as a directive did not help solve this problem. Interestingly, the expression {{codebase}} always works; perhaps it evaluates first, causing Flash to load and try to extract the url?

How would you rewrite this directive (or use a simpler approach) so that the object tag is not created until flashURL is available?

+4
source share
1 answer

I ran into a similar problem trying to embed a PDF through a directive. The problem is that when the template is placed in the DOM, the bindings have not yet been interpolated, as @mfelix suggests. However, this is more complicated, because object calls the code outside the browser, therefore, it is not guaranteed to reproduce incorrect or dynamic attributes well (it depends on the plugin that I assume).

I had to write a link function, which is $observes variable, as in the solution ng-src / ng-href . In the case of ng-src or ng-href $observe for the variable simply sets the corresponding attribute, and everything works because HTML5 (or, as we called it, DHTML) is famously similar to this. For example, you might have a <a> tag without the corresponding href . The browser does a great job of this. And when you install href for it after the first Angular digest, the browser can handle it. But for the <object> it does not work so well, because even if the plug-in is not configured correctly (say, the src attribute is missing), the browser does not know this, and it will still refer to the corresponding plug-in, which will process the missing information in a very peculiar way. In my case, Firefox handled it gracefully and Chrome barfed.

So, the next approach I tried was to use the $observing to insert a child element containing the fully specified object tag (concatenate this line into a template line using the + operator).

A simplified definition of an example directive:

 scope: ... link: function(scope, element, attrs) { attrs.$observe('src', function(value) { if (value) { element.html( '<object width="100%" type="application/pdf" data="'+value+'">'); } else { element.html("<div></div>"); // We have to put something into the DOM } }); }, etc: ... 

When src finally matters, and when its value changes, the callback that you register through $ observ will be called.

My third solution, which I liked the most, was to process the PDF files in GIF files and display them as images, completing the overflowing damn plugins (and no, PDF.js didn't cut it). Perhaps you can turn your flash movies into animated .gifs. That would be awesome.

+11
source

Source: https://habr.com/ru/post/1211092/


All Articles