2013-03-08 10 views
11

Vorrei iniziare dicendo che quello che sto cercando di fare probabilmente non è considerato una buona pratica. Tuttavia, ho bisogno di fare qualcosa di simile al fine di migrare una grande app Web in AngularJs in piccoli passaggi incrementali.Angolare: è possibile guardare una variabile globale (I.e al di fuori di un ambito)?

Ho provato a fare

$scope.$watch(function() { return myVar; }, function (n, old) { 
        alert(n + ' ' + old); 
       }); 

Dove myVar è una variabile globale (definito sulla finestra)

E myVar quindi modificando dalla console. Ma si attiva solo quando si imposta per la prima volta l'osservatore.

Funziona se aggiorno myVar dall'interno del controller (vedi http://jsfiddle.net/rasmusvhansen/vsDXz/3/, ma non se si aggiorna da qualche eredità javascript

Esiste un modo per raggiungere questo obiettivo?

Aggiornamento Mi piace La risposta di Anders è che se il codice legacy è completamente off limits, al momento sto guardando questo approccio che sembra funzionare e non include un timer che scatta ogni secondo:

// In legacy code when changing stuff  
$('.angular-component').each(function() { 
     $(this).scope().$broadcast('changed'); 
}); 

// In angular 
$scope.$on('changed', function() { 
    $scope.reactToChange(); 
}); 

Sto assegnando punti a Anders anche se andrò con un'altra soluzione, poiché la sua soluzione risolve correttamente il problema indicato.

+0

probabilmente non si vuole utilizzare 'each' per la trasmissione in modo angolare fa una sola digest – charlietfl

+1

Nel tuo codice di esempio, a cosa puntava '.angular-component'? – mlhDev

+0

Nel mio caso, ho selezionato l'elemento che volevo effettivamente cambiare (usando 'angular.element (document.getElementById())' perché non stavo usando jQuery), quindi chiamato 'scope(). $ Broadcast ('customEventName'); '. Nota che dovevo usare '$ apply()' all'interno della funzione '$ on ('customEventName')' per far chiamare gli osservatori. –

risposta

12

Il problema qui è probabilmente che stai modificando myVar dall'esterno del mondo Angolare. Angular non esegue cicli di digest/checks sporchi tutto il tempo, solo quando accadono cose in un'applicazione che dovrebbe attivare un digest, come eventi DOM di cui Angular sa qualcosa. Quindi, anche se è stato modificato myVar, Angular non vede alcun motivo per avviare un nuovo ciclo di digest, poiché non è successo nulla (almeno che Angular ne sia a conoscenza).

Quindi, per sparare l'orologio, è necessario forzare Angolare per eseguire un digest quando si modifica myVar. Ma che sarebbe un po 'ingombrante, penso che sarebbe meglio di per creare un oggetto osservabile globale, qualcosa di simile:

<!doctype html> 
<html ng-app="myApp"> 
<head> 
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
    <script src="http://code.angularjs.org/1.0.5/angular.min.js"></script> 
    <script> 
    // Outside of Angular 
    window.myVar = {prop: "value1"}; 
    var myVarWatch = (function() { 
     var watches = {}; 

     return { 
      watch: function(callback) { 
       var id = Math.random().toString(); 
       watches[id] = callback; 

       // Return a function that removes the listener 
       return function() { 
        watches[id] = null; 
        delete watches[id]; 
       } 
      }, 
      trigger: function() { 
       for (var k in watches) { 
        watches[k](window.myVar); 
       } 
      } 
     } 
    })(); 

    setTimeout(function() { 
     window.myVar.prop = "new value"; 
     myVarWatch.trigger(); 
    }, 1000); 

    // Inside of Angular 
    angular.module('myApp', []).controller('Ctrl', function($scope) { 
     var unbind = myVarWatch.watch(function(newVal) { 
      console.log("the value changed!", newVal); 
     }); 

     // Unbind the listener when the scope is destroyed 
     $scope.$on('$destroy', unbind); 
    }); 
    </script> 
</head> 
<body ng-controller="Ctrl"> 

</body> 
</html> 
+1

Grazie per l'input Anders, penso che questo sia un modo molto usabile di farlo se non c'è modo di cambiare il codice legacy. Sono in grado di apportare piccole modifiche al codice legacy, quindi penso di avere un approccio diverso (vedi il mio aggiornamento) – rasmusvhansen

+1

Btw, controlla 'Object.observe()'. Ti permette di guardare le modifiche su un oggetto. Non è ancora implementato in molti browser, ma ci sono polifragi per questo. –

+0

Avevo bisogno di usare $ scope. $ Applicare all'interno dell'angolare myVarWatch.watch per avere un riassunto angolare delle modifiche. – willJk

Problemi correlati