通过 <object> 显示 Flash 的 Angular 指令标签导致 Flash 尝试加载 {{expression}} [英] Angular directive to display Flash via <object> tag causes Flash to attempt to load {{expression}}

查看:15
本文介绍了通过 <object> 显示 Flash 的 Angular 指令标签导致 Flash 尝试加载 {{expression}}的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 AngularJS 指令:

myApp.directive('电影', function(){返回 {限制:'E',替换:真的,范围:{产品:'=',代码库:'@'},模板:'<object style="width:550px;height:320px;"name="电影" id="电影" codebase="{{codebase}}"' +' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" tabindex="-1">'+'<param value="{{product.flashURL}}" name="电影">'+'<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">'+'</对象>'};});

它是这样使用的:

我通过简单地将这个 HTML 包含在视图中来解决我遇到的问题,即:在呈现对象标签的瞬间,Flash 尝试在 URL{{product.html"加载电影.flashURL}}".这显然失败了,当 Angular 开始插入表达式时,为时已晚.

不幸的是,将其重组为指令并没有帮助解决问题.有趣的是,{{codebase}} 表达式似乎总是有效;也许它首先评估,导致 Flash 加载并尝试获取 URL?

您将如何重写此指令(或使用一些更简单的方法),以便在 flashURL 可用之前不会创建对象标记?

解决方案

我在尝试通过指令嵌入 PDF 时遇到了类似的问题.问题在于,当模板被放入 DOM 时,绑定还没有被插入,正如@mfelix 所假设的那样.然而,它更棘手,因为 object 在浏览器之外调用代码,因此不能保证无效或动态属性(取决于我想的插件).

我最终不得不编写一个 link 函数,该函数$observes 变量,就像在 ng-src/ng-href 解决方案.在 ng-srcng-href 的情况下,变量上的 $observe 回调只是设置相应的属性,一切正常,因为 HTML5(或者我们过去称它为 DHTML)就是这么酷.例如,您可能有一个 标签,而没有相应的 href.浏览器处理得很好.当你在第一个 Angular 摘要之后设置一个 href 时,浏览器可以处理它.但是对于 <object> 标签,它并没有那么好用,因为即使插件配置错误(比如,缺少 src 属性),浏览器也无法知道,它会仍然调用相应的插件,它将以高度特殊的方式处理丢失的信息.就我而言,Firefox 优雅地处理了它,而 Chrome 则停止了运行.

所以我尝试的下一个方法是使用 $observing 回调来注入包含完全指定的 object 标记的子元素(使用+ 运算符).

简化示例指令定义:

范围:...链接:函数(范围,元素,属性){attrs.$observe('src', function(value) {如果(值){元素.html('<object width="100%" type="application/pdf" data="'+value+'">');} 别的 {element.html("

");//我们必须往 DOM 中放入一些东西}});},等等: ...

src 最终有了一个值,并且当它的值发生变化时,你通过 $observe 注册的回调将被调用.

我最喜欢的第三个解决方案是将 PDF 处理为 GIF 并将它们显示为图像,完成放弃该诅咒的插件(不,PDF.js 没有剪掉它).所以也许你可以把你的 Flash 电影变成动画 .gifs.那太棒了.

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 like this:

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

I made this directive to fix the problem I was having by simply including this HTML in a view, which is this: the instant the object tag is rendered, the Flash attempts to load a movie at the URL "{{product.flashURL}}". That obviously fails, and by the time Angular gets around to interpolating the expression, it's too late.

Unfortunately, restructuring it as a directive didn't help the problem. Interestingly, the {{codebase}} expression seems to always work; maybe it evaluates first, causing the Flash to load and attempt to fetch the URL?

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

解决方案

I ran into a similar issue trying to embed a PDF via directive. The problem is that when the template is placed into the DOM the bindings have not yet been interpolated, as @mfelix supposes. However it is trickier because object invokes code outside the browser so it isn't guaranteed to play well with invalid or dynamic attributes (depends on the plugin I suppose).

I wound up having to write a link function, which $observes the variable, just as in the ng-src/ng-href solution. In the case of ng-src or ng-href, the $observe callback on the variable simply sets the corresponding attribute and everything works because HTML5 (or as we used to call it, DHTML) is cool like that. For example, you might have an <a> tag without a corresponding href. The browser handles this just fine. And when you set an href on it after the first Angular digest, the browser can deal with it. But for the <object> tag, it doesn't work so well, because even if the plugin is misconfigured (say, missing src attribute), the browser has no way of knowing that and it will still invoke the corresponding plugin, which will treat missing information in a highly idiosyncratic way. In my case, Firefox handled it gracefully and Chrome barfed.

So the next approach I tried was to use the $observing callback to inject a child element containing the fully specified object tag (concatenating the variable into the template string using the + operator).

Simplified example directive definition:

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 has a value, and when its value changes, the callback you register via $observe will be invoked.

My third solution, which I like best, was to process the PDFs into GIFs and display them as images, completing forgoing accursed plugins (and no, PDF.js wasn't cutting it). So maybe you can turn your Flash movies into animated .gifs. That would be awesome.

这篇关于通过 &lt;object&gt; 显示 Flash 的 Angular 指令标签导致 Flash 尝试加载 {{expression}}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆