2013-08-24 34 views
6

Używam usługi do udostępniania danych między kontrolerami. Aplikacja musi zaktualizować DOM, gdy zmienna jest modyfikowana. Znalazłem dwa sposoby, aby to zrobić, można zobaczyć kod tutaj:

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

W pierwszym przypadku udostępniam zmienną z usługi kontrolerowi i $ obejrzyj ją w dyrektywie. Tutaj mogę zmodyfikować zmienną bezpośrednio w tym kontrolerze lub dowolnym innym kontrolerze, który go udostępnia, a DOM jest aktualizowany.

W drugiej opcji używam funkcji z usługi, aby zmodyfikować zmienną, którą $ transmituje wydarzenie. To wydarzenie jest słuchane przez kontroler, a następnie DOM jest aktualizowany.

Chciałbym wiedzieć, która opcja jest lepsza i dlaczego tak się dzieje.

Dzięki.

EDIT:

Kod w jsFiddle, to uproszczona wersja prawdziwego kodu, który ma więcej obiektów i funkcji. W usłudze pole wartości myVariable jest w rzeczywistości obiektem o znacznie większej ilości informacji niż typ pierwotny; informacje te muszą być wyświetlane i aktualizowane w DOM. Obiekt myVariable.value jest ustawiany przy każdej zmianie:

myVariable.value = newValue; 

Kiedy to się dzieje, wszystkie elementy DOM muszą zostać zaktualizowane. Ponieważ informacje zawarte w zmiennej myVariable.value są zmienne, liczba zmian właściwości (nie mogę korzystać z tablicy), znacznie łatwiej jest usunąć elementy DOM i utworzyć nowe, co robię w dyrektywie (ale z większą liczbą elementów w rzeczywistym kodzie):

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

     }); 

Odpowiedz

1

Twój kod jest zawyżony. Nie jestem pewien, co próbujesz zrobić z tą dyrektywą.

Nie musisz niczego od $watch ani $broadcast.

Masz obiekt w swojej usłudze, który ma prymitywę. W CTRL1 jesteś przypisanie obiektu do $scope (To jest dobre, bo jeśli przypiszemy je do prymitywnych, będzie potrzebował $watch na pewno jak widać here.

tej pory tak dobrze. Aby zwiększyć wartość, jest prosty sposób na zrobienie myVal++ bez zmiennych tymczasowych

Dla dyrektywy, nie jestem pewien, jaki jest twój cel tutaj, uprościłem go do tego, czego potrzebujesz, aby ten przykład zadziałał. do $watch ani $broadcast.ctrl1 jest świadomy zmian dokonanych w obiekcie myVariable, więc jeśli ulegnie zmianie, zauważysz to.

Kod:

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

Widok:

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

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


</body> 

Oto mój rozwidlony skrzypce: http://jsfiddle.net/uWdUJ/ sam pomysł trochę oczyścić.

+0

Dzięki, przepraszam, że nie podałam więcej szczegółów. Edytowałem post. – sosegon

+1

Nadal nie widzę potrzeby usuwania i dodawania domeny. Ale jeśli chcesz w ten sposób, wtedy mówię "$ watch". –