2013-10-19 5 views
32

AngularJSとディレクティブの非常に基本的な例に問題があります。 私はwebrtcでWebカメラ画像を表示する指示文を作成したいと思います。 私のコードは完全に流れを示したが、私は(キャンバスをリフレッシュするために、たとえば)のタイムアウトを追加した場合$タイムアウトは、これはコードです 動作しません:

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 
      ); 
     } 
     } 
    }); 

問題は何ですか?このような状況で$タイムアウトが機能しないのはなぜですか?最後に解決策がありますか?

感謝の事前

答えて

14

であなたのコードであなたのコメントには、「は一つだけ 『合格』を示して」と言います。タイムアウトは、指定された遅延後に1回だけ実行されます。

おそらく、setInterval(前角1.2の場合)/ $ interval(1.2から新しい)を使用して、定期的な呼び出しを設定します。ここでのsetIntervalバージョンです:

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

が、私は$これは、外部のjQueryあるので、あなたは(あなたが任意の適切な変更を加えた場合)、DOMを更新するために、角指示する必要があり呼び出すことをメモとして適用されます含まれています。私はここに、あなたの疑問を持っている場合

+0

Ufff .... これは正しいです! 良い一日があります – cingusoft

+2

RC版(1.2.x)を使用している場合は、 'setInterval'と' $ scope。$ apply'の代わりに '$ interval'を使うことを検討してください。 '$ interval'はDOMの更新を気にします。 –

5

わからない($タイムアウトであることは、角度のバージョンが自動的にDOMを更新します)が、$timeoutはかなりのJavaScriptプレーンsetTimeout機能と同じことである、とのように対立するものとして、それは、一度だけ実行を想定していますsetInterval

角度1.2.0を使用している場合は$timeoutサービスを$intervalに変更してください。あなたは1.0バージョンにしているそうでない場合、あなたはそれが再帰的に行うことができます:

var timeout; 
var update = function() { 
    // clear previous interval 
    timeout && timeout(); 
    timeout = $timeout(function() { 
    // drawSomething(...); 
    update(); 
    }, 2000); 
} 
+0

こんにちは@CaioToON、これは私がやったことですが、今は魅力のように動作します。 私は$ intervalと$ timeoutを混同しました。 – cingusoft

+0

'$ timeout'とjavascriptの' setTimeout'には1つの違いがあります。 '$ digest'サイクル内で' $ timeout'が実行されます(モデルに変更を加えるために '$ apply'関数を呼び出す必要はありません)。もちろん、$ timeoutは約束します。 –

+0

タイムアウトにも興味深いプロパティがあります。タイムアウト間隔なしに設定すると、DOMがレンダリングされるまで待機する遅延として機能します。 –

74

あなたは他のモジュールのようにディレクティブに依存性を注入することができます:あなたの時間を無駄にして申し訳ありません

.directive('myDirective', ['$timeout', function($timeout) { 
    return { 
     ... 
     link: function($scope, element){ 
      //use $timeout 
     } 
    }; 
}]); 
+3

誰でもコピーするには、 '='は必要ありません。 –

関連する問題