2013-10-19 84 views
32

我對AngularJS和指令非常基本的例子有問題。 我想創建一個指令,用webrtc顯示攝像頭圖像。 我的代碼顯示流完美,但如果我添加超時(例如刷新畫布)在$超時不工作 這是代碼:

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

在你的代碼,您的評論說,「只顯示一個‘通’」。超時只在指定的延遲後執行一次。

也許你想setInterval(如果你是預先角1.2)/ $間隔(新到1.2),它建立了一個定期調用。這裏的setInterval的版本:

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

我包括$應用作爲一個提醒,因爲這是一個外部的jQuery叫你需要告訴角度來更新DOM(如果你做任何適當的更改)。 ($超時是一個角度版本自動更新DOM)

+0

UFFF抱歉浪費你的時間.... 這是正確的! 祝你有美好的一天 – cingusoft

+2

如果你使用RC版本(1.2.x),考慮使用'$ interval'而不是'setInterval'和'$ scope。$ apply'。 '$ interval'會關心你的DOM刷新。 –

5

不知道如果我在這裏得到你的懷疑,但$timeout是幾乎相同的東西,與javascript普通setTimeout功能,它應該只運行一次,而不是setInterval

如果您使用的是Angular 1.2.0,請通過$interval更改$timeout服務。如果不是的話,你是在1.0版本中,你可以把它遞歸:

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

嗨@CaioToON,這就是我所做的,現在像魅力一樣工作。 我已經把$ timeout與$ interval混淆了。 – cingusoft

+0

'$ timeout'和javascript的'setTimeout'有一個區別 - '$ timeout'在'$ digest'循環中執行(您不需要調用'$ apply'函數在模型中應用更改)。當然'$ timeout'會帶來承諾。 –

+0

超時也有一個有趣的屬性,如果設置沒有超時間隔,那麼它將作爲延遲等待DOM呈現。 –

74

您可以像其他模塊注入依賴的指令:

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

對於任何人複製,你不需要'=' –