Angular JS 和 Directive Link 和 $timeout

Posted

技术标签:

【中文标题】Angular JS 和 Directive Link 和 $timeout【英文标题】:Angular JS and Directive Link and $timeout 【发布时间】:2013-10-28 14:51:44 【问题描述】:

我对 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
           );
         
       
    );

有什么问题?为什么 $timeout 在这种情况下不起作用?终于有办法了吗?

先谢谢了

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

对于复制的任何人,您不需要'='【参考方案2】:

在您的代码中,您的评论说“仅显示一个“通过”。 Timeout 仅在指定的延迟之后执行一次。

也许您想要 setInterval(如果您是 Angular 1.2 之前的版本)/ $interval(1.2 的新版本),它会设置一个循环调用。这是 setInterval 版本:

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

我包含 $apply 作为提醒,因为这是一个外部 jQuery 调用,您需要告诉 angular 更新 DOM(如果您进行了任何适当的更改)。 ($timeout 是 Angular 版本会自动更新 DOM)

【讨论】:

如果您使用的是 RC 版本 (1.2.x),请考虑使用 $interval 而不是 setInterval$scope.$apply$interval 会为你处理 DOM 刷新。【参考方案3】:

不确定我是否在这里遇到了你的疑问,但 $timeoutjavascript 普通的 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);

【讨论】:

嗨@CaioToON,这就是我所做的,现在工作就像一个魅力。我把 $timeout 和 $interval 搞混了。 $timeout 和 javascript 的 setTimeout 有一个区别 - $timeout$digest 循环内执行(您不需要调用 $apply 函数来应用模型中的更改)。当然$timeout 会得到一个承诺。 Timeout 也有一个有趣的属性,如果没有设置超时时间间隔,那么它会延迟等待直到 DOM 渲染完毕。 当您不指定超时时,任务将作为事件循环中的下一个微任务执行。这不一定意味着 DOM 会被渲染,但它有可能会。

以上是关于Angular JS 和 Directive Link 和 $timeout的主要内容,如果未能解决你的问题,请参考以下文章

基于angular的分页组件插件,使用directive,将directive的内容放到js文件中,直接引用即可

angular js中的directive

相对于 .js 文件的 Angular 指令 templateUrl

Angular JS 中 指令详解

学习AngularJs:Directive指令用法(完整版)

Angular 中的 @Directive 与 @Component