通过<object>标签显示Flash的Angular指令会导致Flash尝试加载{{expression}}

mfe*_*lix 4 angularjs angularjs-directive

我有一个AngularJS指令:

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>'
};});
Run Code Online (Sandbox Code Playgroud)

它是这样使用的:

<movie product="productInScope" codebase="http://flashcodebase..." />
Run Code Online (Sandbox Code Playgroud)

我通过简单地在视图中包含此HTML来制定此指令以解决我遇到的问题,即:呈现对象标记的瞬间,Flash尝试在URL"{{product.flashURL}}处加载电影".这显然是失败的,当Angular绕过插值表达时,已经太晚了.

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

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

Bre*_*ett 11

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

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

因此,我尝试的下一个方法是使用$observing回调来注入包含完全指定object标记的子元素(使用+运算符将变量连接到模板字符串中).

简化的示例指令定义:

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: ...
Run Code Online (Sandbox Code Playgroud)

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

我最喜欢的第三个解决方案是将PDF处理成GIF并将其显示为图像,完成放弃诅咒的插件(不,PDF.js没有切割它).所以也许你可以将你的Flash电影变成动画.gif文件.那将是真棒.