Angular JS and Directive Link and $timeout
Solution 1
In your code your comment says 'show only one "pass"'. Timeout only executes one time, after the specified, delay.
Perhaps you want setInterval (if you're pre angular 1.2)/ $interval (new to 1.2) which sets up a recurring call. Here's the setInterval version:
var timeout = setInterval(function(){
// do stuff
$scope.$apply();
}, 2000);
I included $apply as a reminder that since this is an external jQuery call you need to tell angular to update the DOM (if you make any appropriate changes). ($timeout being an angular version automatically updates the DOM)
Solution 2
You can inject dependencies to the directive like in other modules:
.directive('myDirective', ['$timeout', function($timeout) {
return {
...
link: function($scope, element){
//use $timeout
}
};
}]);
Solution 3
Not sure if I got your doubt here, but $timeout
is pretty much the same thing as javascript plain setTimeout
function, and it is supposed run only once, as opposed as setInterval
.
If you're using Angular 1.2.0, change $timeout
service per $interval
. If otherwise you're on 1.0 version, you can make it recursive:
var timeout;
var update = function() {
// clear previous interval
timeout && timeout();
timeout = $timeout(function() {
// drawSomething(...);
update();
}, 2000);
}
Andrea Mucci
Updated on February 09, 2020Comments
-
Andrea Mucci over 4 years
i have a problem with a very basic example with AngularJS and directives. I want to create a directive that show a webcam image with webrtc. My code show the stream perfectly but if i add a timeout ( for example to refresh a canvas ) the $timeout don't work this is the code:
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 ); } } });
What is the problem? why the $timeout don't work in this conditions? and finally have a solution?
thank's in advance