2

video.jsライブラリをアプリに接続しようとしています。アプリの一部で、ユーザーは動画を含む可能性のあるファイルをアップロードできるため、出力時に を使用しng-repeatて動画のアップロードをループし、HTML5動画タグを出力します。video.jsビデオタグにディレクティブを付けて、一緒に使用できるようにしたいと思います。

私のビデオ出力は次のように定義されています

<video ng-src="{{video.url}}" ng-repeat="video in post.attachments.video" type="{{video.mimetype}}" controls preload="metadata" id="video_{{video.id}}" video>

私のvideoディレクティブでは、基本的にvideojs関数を実行してセットアップしたいだけなので、呼び出したい

videojs(attrs.id, {
    controls: true,
    preload: "metadata",
    techOrder: ["flash"]
  }, function() {});

これは呼び出されていますが、私が抱えている問題はng-repeat、このディレクティブが呼び出されたときに がまだすべてを完了していないattrs.idことvideo_{{video.id}}ですvideo_23

ng-repeatID 属性を使用できることを確認するために、ビデオ ディレクティブが実行される前に が完了するまで待つにはどうすればよいですか?

現在Angular 1.1.4を使用しています。

現在、私のディレクティブは

app.directive("video", function($parse) {
  "use strict";
  return {
    restrict: "A",
    link: function(scope, elm, attrs) {

      videojs(attrs.id, {
        controls: true,
        preload: "metadata",
        techOrder: ["flash"]
      }, function() {});
    }
  };
});
4

3 に答える 3

1

最後に解決策があります。それは(角度のあるコールバックがないため)最高ではありませんが、機能しています。私の最終的な指示は

app.directive("video", function($timeout) {
  "use strict";
  return {
    restrict: "A",
    compile: function(cElm, cAttrs) {
      return function postLink(scope, elm, attrs) {
        // We have to wait until it's actually rendered. Stupid angular with no callback!
        $timeout(function() {
          videojs(scope.$eval(attrs.video), {
            controls: true,
            preload: "metadata",
            techOrder: ["flash"]
          }, function() {});
        })
      }
    }
  };
});

また、htmlの定義を次のように変更する必要がありました

<video ng-src="{{video.url}}" ng-repeat="video in post.attachments.video" type="{{video.mimetype}}" controls preload="metadata" id="video_{{video.id}}" video="'video_' + video.id">

video属性で使用される式は では使用idできないため、属性に式が追加されていることに注意してevalください。

$timeoutangularが要素のレンダリングを完了していなかったため、要素IDでvideo.jsを初期化しようとしても機能しなかったため、迷惑なハックを利用する必要がありました.video.jsがそのIDを持つ要素を見つけようとしたときDOM、それは何にも一致しませんでした。$timeout私はあまり熱心ではありませんが、これを修正して使用しています。

誰かがこれに対するより良い解決策を持っているなら、私はすべて耳にします:)

于 2013-06-30T02:36:55.147 に答える
1

問題は、補間された値にアクセスしようとしているときに、文字列の補間が実行されていないことです。attrs.$observe(...)これを達成するために使用できます。AngularJS のドキュメントへのリンクは次のとおりです (または以下を参照してください)。

...
link: function(scope, element, attrs) {
  attrs.$observe('id', function() {
    videojs(attrs.id, {
      controls: true,
      preload: "metadata",
      techOrder: ["flash"]
    }, function() {});
  });
}
...

この動作を示すプランカーも作成しました。

編集:正解で更新されました。

編集2:Angularのドキュメントから:

$observe補間を含む属性の値の変化を観察するために使用します (例: src="{{bar}}")。これは非常に効率的であるだけでなく、実際の値を簡単に取得する唯一の方法でもあります。これは、リンク段階では補間がまだ評価されておらず、この時点で値が未定義に設定されているためです。

于 2013-06-30T01:04:07.923 に答える
0

priorityディレクティブにa を指定できます。ドキュメントAngularJS: Directivesから:

優先度 - 1 つの DOM 要素に複数のディレクティブが定義されている場合、ディレクティブが適用される順序を指定する必要がある場合があります。優先度は、コンパイル関数が呼び出される前にディレクティブをソートするために使用されます。優先度は数値で定義されます。数値の優先度が高いディレクティブが最初にコンパイルされます。同じ優先度のディレクティブの順序は定義されていません。デフォルトの優先度は 0 です。

編集: 実際、これはこの質問とかなり似ています:カスタム ディレクティブ内で評価された属性を取得する方法

于 2013-06-29T23:18:26.277 に答える