Angolare JS e la Direttiva Link e $timeout

ho un problema con un esempio molto semplice con AngularJS e direttive.
Voglio creare una direttiva che mostra un’immagine webcam con webrtc.
Il mio codice mostra il flusso perfettamente, ma se posso aggiungere un timeout ( per esempio per aggiornare una tela ) il $timeout non funzionano
questo è il codice:

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

Qual è il problema? perché il $timeout di non lavorare in queste condizioni? e, infine, di avere una soluzione?

grazie in anticipo

InformationsquelleAutor cingusoft | 2013-10-19



3 Replies
  1. 14

    Nel codice il tuo commento dice ” mostra solo un “pass”‘. Timeout viene eseguita solo una volta, dopo aver specificato, di ritardo.

    Forse vuoi setInterval (se sei pre angolare 1.2)/$(a intervalli di nuovo a 1,2), che stabilisce una chiamata ricorrente. Ecco il setInterval versione:

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

    Ho incluso $applicare come un promemoria che, trattandosi di un esterno jQuery chiamata è bisogno di dire angolare per aggiornare il DOM (se si apportano modifiche appropriate). ($timeout angolare versione aggiorna automaticamente il DOM)

    • Ufff mi dispiace sprecare il tuo tempo…. esatto!!! buona giornata
    • Se si sta utilizzando la versione RC (1.2.x), considerare l’utilizzo di $interval invece di setInterval e $scope.$apply. $interval si cura il DOM aggiornamento per voi.
  2. 78

    Si possono iniettare le dipendenze della direttiva, come in altri moduli:

    .directive('myDirective', ['$timeout', function($timeout) {
       return {
            ...
            link: function($scope, element){
                //use $timeout
            }
        };
    }]);
    • Per chi copia, non hai bisogno di la ‘=’
  3. 5

    Non sono sicuro se ho avuto il tuo dubbio, ma $timeout è praticamente la stessa cosa come codice javascript pianura setTimeout funzione, e si suppone di eseguire una sola volta, anziché come setInterval.

    Se si utilizza Angolare 1.2.0, modificare $timeout servizio per $intervallo. Se non sei in versione 1.0, si può fare ricorsiva:

    var timeout;
    var update = function() {
      //clear previous interval
      timeout && timeout();
      timeout = $timeout(function() {
        //drawSomething(...);
        update();
      }, 2000);
    }
    • Ciao @CaioToON, questo è quello che ho fatto e ora funziona come un fascino. Ho confuso $timeout con $intervallo.
    • $timeout e javascript setTimeout ha una differenza – $timeout viene eseguita all’interno di $digest ciclo (non c’è bisogno di chiamare $apply funzione per applicare le modifiche nel modello). E, naturalmente, $timeout si tradurrà con una promessa.
    • Timeout ha anche una proprietà interessante, se non l’intervallo di timeout allora serve come un ritardo fino a DOM ha reso.
    • Quando non si specifica il timeout l’attività verrà eseguita la successiva micro-attività nel ciclo di eventi. Essa non significa, necessariamente, che il DOM sarà resa ma c’è una possibilità che.

Lascia un commento