2013-08-24 12 views
6

Ich verwende einen Dienst, um Daten zwischen den Controllern zu teilen. Die Anwendung muss das DOM aktualisieren, wenn eine Variable geändert wird. Ich habe zwei Wege gefunden, das zu tun, Sie den Code sehen hier:

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

Im ersten Fall teile ich eine Variable aus dem Service mit dem Controller und beobachten Sie es in der Direktive. Hier kann ich die Variable direkt in diesem Controller oder einem anderen Controller ändern, der sie gemeinsam nutzt, und das DOM wird aktualisiert.

In der anderen Option, ich benutze eine Funktion aus dem Dienst, um die Variable zu ändern, die ein Ereignis sendet. Dieses Ereignis wird vom Controller abgehört und das DOM wird aktualisiert.

Ich würde gerne wissen, welche Option besser ist und die Gründe dafür.

Danke.

EDIT:

Der Code in jsFiddle, ist eine vereinfachte Version des Real-Code, die mehrere Objekte und Funktionen. Im Dienst ist das Wertfeld von myVariable tatsächlich ein Objekt mit viel mehr Informationen als nur ein primitiver Typ; Diese Informationen müssen im DOM angezeigt und aktualisiert werden. Das Objekt myVariable.value wird in jeder Änderung einstellen:

myVariable.value = newValue; 

Wenn das passiert alle DOM-Elemente aktualisiert werden müssen. Da die in myVariable.value enthaltenen Informationen variabel sind, ändert sich die Anzahl der Eigenschaften (ich kann kein Array verwenden), es ist viel einfacher, die DOM-Elemente zu löschen und neue zu erstellen, das mache ich in der Direktive (aber mit mehr Elementen im realen Code):

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

     }); 

Antwort

1

Ihr Code ist über Komplex. Ich bin mir nicht sicher, was Sie mit dieser Richtlinie zu tun versuchen.

Sie müssen nicht $watch noch $broadcast irgendetwas.

Sie haben ein Objekt in Ihrem Dienst, das ein Primitiv hat. In ctrl1 sind Sie das Objekt an die $scope Zuweisen (Das ist gut, denn wenn wir es auf die primitive zuweisen, wird es eine $watch sicher brauchen als here gesehen.

So weit so gut. Um den Wert zu erhöhen, Es gibt einen einfachen Weg, myVal++ keine Notwendigkeit von temporären Variablen.

Für die Direktive, ich bin nicht sicher, was Ihr Ziel hier ist, vereinfachte ich es, was Sie brauchen, um dieses Beispiel zu arbeiten zu $watch noch $broadcast.ctrl1 ist sich der Änderungen bewusst, die an myVariable Objekt vorgenommen wurden. Wenn es sich ändert, werden Sie es bemerken.

Code:

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

Ausblick:

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

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


</body> 

Hier ist meine gegabelt Geige: http://jsfiddle.net/uWdUJ/ Gleiche Idee ein wenig gereinigt.

+0

Danke, ich entschuldige mich, ich habe keine weiteren Details geben. Ich habe den Beitrag bearbeitet. – sosegon

+1

Ich sehe immer noch nicht die Notwendigkeit, dom zu entfernen und hinzuzufügen. Aber wenn du so willst, dann sage ich '$ watch'. –