2013-08-24 7 views
6

Sto utilizzando un servizio per condividere i dati tra i controller. L'applicazione deve aggiornare il DOM quando una variabile viene modificata. Ho trovato due modi per farlo, si può vedere il codice qui:

http://jsfiddle.net/sosegon/9x4N3/7/

myApp.controller("ctrl1", [ "$scope", "myService", function($scope, myService){ 
    $scope.init = function(){ 
     $scope.myVariable = myService.myVariable; 
    }; 
}]); 

myApp.controller("ctrl2", [ "$scope", "myService", function($scope, myService){ 
    $scope.increaseVal = function(){ 
     var a = myService.myVariable.value; 
     myService.myVariable.value = a + 1; 
    }; 
}]); 

http://jsfiddle.net/sosegon/Y93Wn/3/

myApp.controller("ctrl1", [ "$scope", "myService", function($scope, myService){ 
    $scope.init = function(){ 
     $scope.increasedCounter = 1; 
     $scope.myVariable = myService.myVariable; 
    }; 
    $scope.$on("increased", function(){ 
     $scope.increasedCounter += 1; 
    } 
}]); 

myApp.controller("ctrl2", [ "$scope", "myService", function($scope, myService){ 
    $scope.increaseVal = function(){ 
     myService.increaseVal(); 
    }; 
}]); 

Nel primo caso condivido una variabile dal servizio con il controller e $ la osservo nella direttiva. Qui, posso modificare la variabile direttamente in questo controller o in qualsiasi altro controller che la condivide e il DOM viene aggiornato.

Nell'altra opzione, utilizzo una funzione del servizio per modificare la variabile che $ trasmette un evento. L'evento viene ascoltato dal controller, quindi il DOM viene aggiornato.

Mi piacerebbe sapere quale opzione è migliore e le ragioni per questo.

Grazie.

EDIT:

Il codice in jsFiddle, è una versione semplificata del codice reale che ha più oggetti e funzioni. Nel servizio, il campo valore di myVariable è in realtà un oggetto con molte più informazioni di un semplice tipo primitivo; quell'informazione deve essere visualizzata e aggiornata nel DOM. Il myVariable.value oggetto viene impostato in ogni cambio:

myVariable.value = newValue; 

Quando ciò accade tutti gli elementi DOM devono essere aggiornati. Poiché le informazioni contenute in myVariable.value sono variabili, il numero di proprietà cambia (non posso usare un array), è molto più facile eliminare gli elementi DOM e crearne di nuovi, questo è quello che sto facendo nella direttiva (ma con più elementi nel codice reale):

scope.$watch("myVariable.value", function(newVal, oldVal){ 

      if(newVal === oldVal){ 

       return; 

      } 

      while(element[0].children.length > 0){ 

       element[0].removeChild(element[0].firstChild); 

      } 


      var e = angular.element(element); 
      e.append("<span>Value is: " + scope.myVariable.value + "</span>"); 

     }); 

risposta

1

Il tuo codice è troppo complesso. Non sono sicuro di cosa stai cercando di fare con quella direttiva.

Non è necessario $watch$broadcast nulla.

Hai un oggetto nel tuo servizio che ha una primitiva. In Ctrl1 si sta assegnando l'oggetto alla $scope (Questa è una buona, perché se assegniamo alla primitiva, avrà bisogno di una $watch di sicuro come visto here.

Fin qui tutto bene. Per aumentare il valore, c'è un modo semplice per fare semplicemente le variabili temporanee

Per la direttiva, non sono sicuro di quale sia il tuo obiettivo qui, l'ho semplificato per quello che ti serve per mettere quell'esempio al lavoro. a $watch$broadcast.ctrl1 è a conoscenza delle modifiche apportate all'oggetto myVariable, pertanto se viene modificato, lo si noterà.

Codice:

var myApp = angular.module("myApp", []); 

myApp.provider("myService", function(){ 

    var myVariable = { 
     value: 0 
    }; 
    this.$get = function(){ 
     return { 
      myVariable: myVariable, 
      increase: function() { 
       myVariable.value++; 
      } 
     }; 
    }; 
}); 

myApp.directive("dir1", function(){ 
    return { 
     restrict: 'EA', 
     template: '<div>value: {{myVariable.value}}</div>', 
     replace: true 
    }; 
}); 


myApp.controller("ctrl1", ["$scope", "myService", function($scope, myService){ 
    $scope.myVariable = myService.myVariable; 
}]); 

myApp.controller("ctrl2", [ "$scope", "myService", function($scope, myService){ 
    $scope.increaseVal = myService.increase; 
}]); 

Vista:

<body ng-app = "myApp"> 
    <div dir1="myVariable.value" ng-controller = "ctrl1"> 
    </div> 

    <div ng-controller = "ctrl2"> 
     <button ng-click = "increaseVal()"> 
      Increase 
     </button> 
    </div> 


</body> 

Ecco il mio violino biforcuta: http://jsfiddle.net/uWdUJ/ Stessa idea un po 'pulito.

+0

Grazie, mi scuso per non aver fornito ulteriori dettagli. Ho modificato il post. – sosegon

+1

Ancora non vedo la necessità di rimuovere e aggiungere dom. Ma se vuoi in questo modo, io dico "$ watch" allora. –