34

AngularJS とディレクティブを使用した非常に基本的な例に問題があります。webrtc で Web カメラ画像を表示するディレクティブを作成したいと考えています。私のコードはストリームを完全に表示しますが、タイムアウトを追加すると (たとえば、キャンバスを更新するために) $timeout が機能しません。これはコードです:

wtffDirectives.directive('scannerGun',function($timeout){
    return {
        restrict: 'E',
        template: '<div>' +
            '<video ng-hide="videoStatus"></video>' +
            '<canvas id="canvas-source"></canvas>' +               
            '</div>',
        replace: true,
        transclude: true,
        scope: false,
        link: function postLink($scope, element){
           $scope.canvasStatus = true;
           $scope.videoStatus = false;

           width = element.width = 320;
           height = element.height = 0;

           /* this method draw the webcam image into a canvas */
           var drawVideoCanvas = function(){
              sourceContext.drawImage(vid,0,0, vid.width, vid.height);
           };

           /* start the timeout that take a screenshot and draw the source canvas */
           var update = function(){
              var timeout = $timeout(function(){
                console.log("pass"); //the console log show only one "pass"
                //drawVideoCanvas();
              }, 2000);
           };

           /* this work perfectly and reproduct into the video tag the webcam */
           var onSuccess = function onSuccess(stream) {
              // Firefox supports a src object
              if (navigator.mozGetUserMedia) {
                 vid.mozSrcObject = stream;
              } else {
                 var vendorURL = window.URL || window.webkitURL;
                 vid.src = vendorURL.createObjectURL(stream);
              }
              /* Start playing the video to show the stream from the webcam*/
              vid.play();
              update();
           };

           var onFailure = function onFailure(err) {

              if (console && console.log) {
                console.log('The following error occured: ', err);
              }
              return;
           };

           var vid = element.find('video')[0];
           var sourceCanvas = element.find('canvas')[0];
           var sourceContext = sourceCanvas.getContext('2d');

           height = (vid.videoHeight / ((vid.videoWidth/width))) || 250;
           vid.setAttribute('width', width);
           vid.setAttribute('height', height);

           navigator.getMedia (
              // ask only for video
              {
                video: true,
                audio: false
              },
              onSuccess,
              onFailure
           );
         }
       }
    });

何が問題ですか?この条件で $timeout が機能しないのはなぜですか? そして最終的に解決策がありますか?

前もって感謝します

4

3 に答える 3

15

あなたのコードでは、あなたのコメントは「1つの「パス」のみを表示する」と言っています。タイムアウトは、指定された遅延の後に 1 回だけ実行されます。

おそらく、繰り返し呼び出しを設定する setInterval (angular 1.2 より前の場合)/ $interval (1.2 の新機能) が必要です。setInterval バージョンは次のとおりです。

var timeout = setInterval(function(){
    // do stuff
    $scope.$apply();
}, 2000); 

$apply を含めたのは、これは外部 jQuery 呼び出しであるため、angular に DOM を更新するように指示する必要がある (適切な変更を行った場合) ことを思い出させるためです。(Angular バージョンである $timeout は DOM を自動的に更新します)

于 2013-10-19T23:49:30.690 に答える
5

ここであなたの疑問が生じたかどうかはわかりませんが、 JavaScript のプレーン関数と$timeoutほとんど同じであり、 .setTimeoutsetInterval

Angular 1.2.0 を使用している場合は、$timeoutサービスごとに変更します$interval。それ以外の場合は、バージョン 1.0 を使用している場合は、再帰的にすることができます。

var timeout;
var update = function() {
  // clear previous interval
  timeout && timeout();
  timeout = $timeout(function() {
    // drawSomething(...);
    update();
  }, 2000);
}
于 2013-10-19T23:53:40.303 に答える