Angular JS和Directive Link以及$ timeout

And*_*cci 34 javascript timeout angularjs angularjs-directive

我对AngularJS和指令的一个非常基本的例子有一个问题.我想创建一个使用webrtc显示网络摄像头图像的指令.我的代码完美地显示了流,但如果我添加超时(例如刷新画布),$ 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
           );
         }
       }
    });
Run Code Online (Sandbox Code Playgroud)

问题是什么?为什么$ timeout在这种情况下不起作用?最后有一个解决方案?

提前致谢

Paw*_*tyć 78

您可以像在其他模块中一样将依赖项注入指令:

.directive('myDirective', ['$timeout', function($timeout) {
   return {
        ...
        link: function($scope, element){
            //use $timeout
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

  • 对于任何人复制,你不需要'=' (3认同)

Kay*_*ave 14

在您的代码中,您的评论显示"只显示一个"通过"'.超时仅在指定的延迟后执行一次.

也许你想要setInterval(如果你是前角1.2)/ $ interval(新到1.2),它设置一个定期调用.这是setInterval版本:

var timeout = setInterval(function(){
    // do stuff
    $scope.$apply();
}, 2000); 
Run Code Online (Sandbox Code Playgroud)

我包括$ apply作为提醒,因为这是一个外部jQuery调用,你需要告诉angular更新DOM(如果你做了任何适当的更改).($ timeout是一个角度版本自动更新DOM)

  • 如果您使用RC版本(1.2.x),请考虑使用`$ interval`而不是`setInterval`和`$ scope.$ apply`.`$ interval`会关心你的DOM刷新. (2认同)

Cai*_*nha 5

不确定我是否在这里遇到了疑问,但$timeout与javascript普通setTimeout函数几乎相同,并且它应该只运行一次,而不是setInterval.

如果您使用的是Angular 1.2.0,请更改$timeout每个服务$interval.如果不是你的1.0版本,你可以使它递归:

var timeout;
var update = function() {
  // clear previous interval
  timeout && timeout();
  timeout = $timeout(function() {
    // drawSomething(...);
    update();
  }, 2000);
}
Run Code Online (Sandbox Code Playgroud)