2013-03-11 8 views
12

Brakuje tu czegoś oczywistego. W mojej dyrektywie mam działające dwukierunkowe powiązanie danych, ale nie mogę użyć opcji $ scope. $ Watch() do monitorowania zmian, które mogą wystąpić w obiekcie Js obiektu nadrzędnego dyrektywy.

http://jsfiddle.net/Kzwu7/6/

Jak widać, gdy próbuję użyć $ oglądać na attrs.dirModel otrzymaną wartość jest niezdefiniowana i nic się dalej obserwował, chociaż ja modyfikację obiektu po krótkim opóźnieniem. Próbowałem również używać (i nie używać) prawdziwej flagi w instrukcji $ watch.

HTML:

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script> 

<div ng-app="test" ng-controller="MainCtrl"> 
    <dir dir-model="model"></dir> 
    <p>{{model.tbdTwoWayPropA}}</p> 
</div> 

<script type="text/ng-template" id="template"> 
    <div class="test-el">{{dirModel.tbdTwoWayPropB}}</div> 
</script> 

JS:

var app = angular.module('test', []); 

app.controller("MainCtrl", [ 
    "$scope", "$timeout", 
    function($scope, $timeout){ 
     $scope.model = { 
      tbdTwoWayPropA: undefined, 
      tbdTwoWayPropB: undefined, 
      tbdTwoWayPropC: undefined 
     } 

     // TBD Ajax call 
     $timeout(function(){ 

      // alert("Model updated, but $scope.$watch isn't seeing it."); 

      $scope.model.tbdTwoWayPropA = 1; 
      $scope.model.tbdTwoWayPropB = 30; 
      $scope.model.tbdTwoWayPropC = [{ a: 1 },{ a: 2 },{ a: 3 }]; 

     }, 2000) 
    } 
]); 

app.directive('dir', [ 
    "$timeout", 
    function($timeout) { 
     return { 
      restrict: "E", 
      controller: function($scope){ 
       $scope.modifyTwoWayBindings = function(){ 

        // Two-way bind works 
        $scope.dirModel.tbdTwoWayPropA = 2; 
       } 

       $timeout(function(){ 
        $scope.modifyTwoWayBindings(); 
       }, 4000); 
      }, 
      scope: { 
       dirModel: '=' 
      }, 
      template: $("#template").html(), 
      replace: true, 
      link: function($scope, element, attrs) { 

      $scope.$watch(attrs.dirModel, handleModelUpdate, true); 

       // alert(attrs.dirModel); 

       function handleModelUpdate(newModel, oldModel, $scope) { 
        alert('Trying to watch mutations on the parent js object: ' + newModel); 
       } 
      } 
     } 
}]); 

Odpowiedz

19

Ponieważ używasz '=', masz lokalną własność dyrektywa zakres dirModel. Po prostu obejrzyj to:

$scope.$watch('dirModel', handleModelUpdate, true); 
+0

Dziękuję. Czy znasz dobry zasób, aby dowiedzieć się więcej o "właściwości zakresu dyrektywy lokalnej". Wcześniej widziałem tylko przykłady uzyskujące dostęp do argumentu atrybuty. Ostatnie skrzypce JS dla odniesienia użytkowników. http://jsfiddle.net/Kzwu7/8/ – BradGreens

+0

@BradGreens, cóż, jest wspomniany na niezbyt łatwej do zrozumienia [stronie dyrektyw] (http://docs.angularjs.org/guide/directive) w sekcji "Definicja dyrektywy". Zobacz także http://stackoverflow.com/questions/14050195/what-is-the-difference-between-and-in-directive-scope/14063373#14063373, http://stackoverflow.com/questions/14908133/what- is-the-difference-between-vs-in-angularjs i http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-initance-in-angularjs/14049482 # 14049482 (patrz sekcja "dyrektywy" w dolnej części). –

+0

Przeczytałem to wiele razy;). Myślę, że teraz jestem szczególnie zainteresowany nauczeniem się, jakie metody kątowe zaakceptują tę łańcuchową reprezentację atrybutu jako parametru. tj. $ obserwuj ("attr", fct), $ set ("attr", "val"), $ watch ("attr", fct) itd. Reprezentacja łańcuchów jest trochę magiczna. – BradGreens

Powiązane problemy