4

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?


id in this case is not the id attribute of an element, but a field named "id" in the form.

Simplified it looks like this:

<form>
<input name="id" value="some:page">
<textarea>the editor</textarea>
</form>

dw_linkwiz.textArea is the DOM object of the textarea. dw_linkwiz.textArea.form.id.value is "some:page".

4

1 に答える 1

11

ディレクティブを介して PDF を埋め込もうとして、同様の問題に遭遇しました。問題は、テンプレートが DOM に配置されたときに、@mfelix が想定しているように、バインディングがまだ補間されていないことです。ただしobject、ブラウザの外部でコードを呼び出すため、無効な属性または動的な属性でうまく機能することが保証されていないため、より注意が必要です (私が推測するプラグインによって異なります)。

/ソリューションと同じように、変数であるlink関数を作成する必要がありました。またはの場合、変数のコールバックは単に対応する属性を設定するだけで、HTML5 (または以前は DHTML と呼んでいた) はそのようにクールであるため、すべてが機能します。たとえば、対応する のないタグがある場合があります。ブラウザはこれをうまく処理します。そして、最初の Angular ダイジェストの後に を設定すると、ブラウザーはそれを処理できます。しかし、$observesng-srcng-hrefng-srcng-href$observe<a>hrefhref<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: ...

最終的にsrc値があり、その値が変更されると、$observe を介して登録したコールバックが呼び出されます。

私が最も気に入っている 3 番目の解決策は、PDF を GIF に処理し、それらを画像として表示することでした。そのため、Flash ムービーをアニメーション .gif に変換できるかもしれません。それは素晴らしいでしょう。

于 2013-03-08T01:19:09.967 に答える