2013-08-31 12 views
24

Próbuję napisać dyrektywę, która wykorzystuje izolowany zakres i dyrektywę ngModel.Dyrektywa z izolowanym zakresem i modelem ng

Problem:
Po zaktualizowaniu modelu w dyrektywie wartość osoby dzwoniącej nie jest aktualizowana.

HTML:

<test-ng-model ng-model="model" name="myel"></test-ng-model> 

dyrektywa:

app.directive(
    'testNgModel', [ 
    '$timeout', 
    '$log', 

function ($timeout, $log) { 

    function link($scope, $element, attrs, ctrl) { 
     var counter1 = 0, counter2 = 0; 

     ctrl.$render = function() { 
      $element.find('.result').text(JSON.stringify(ctrl.$viewValue)) 
     } 

     $element.find('.one').click(function() { 
      if ($scope.$$phase) return; 
      $scope.$apply(function() { 
       var form = angular.isObject(ctrl.$viewValue) ? ctrl.$viewValue : {}; 
       form.counter1 = ++counter1; 
       ctrl.$setViewValue(form); 
      }); 
     }); 
     $element.find('.two').click(function() { 
      if ($scope.$$phase) return; 
      $scope.$apply(function() { 
       var form = angular.isObject(ctrl.$viewValue) ? ctrl.$viewValue : {}; 
       form.counter2 = ++counter2; 
       ctrl.$setViewValue(form); 
      }); 
     }); 

     $scope.$watch(attrs.ngModel, function (current, old) { 
      ctrl.$render() 
     }, true) 
    } 

    return { 
     require: 'ngModel', 
     restrict: 'E', 
     link: link, 
     //if isolated scope is not set it is working fine 
     scope: true, 
     template: '<div><input type="button" class="one" value="One"/><input type="button" class="two" value="Two"/><span class="result"></span></div>', 
     replace: true 
    }; 

}]); 

Demo: Fiddle

Jeżeli izolowane zakres nie jest ustawiony to działa dobrze: fiddle

+1

'zakres: TRUE nie tworzy zakres izolować, to tworzy nowy zakres podrzędny, który prototypowo dziedziczy z zakresu nadrzędnego, stąd powód '$ parent.model' działa. (Zakres izolatu jest tworzony, gdy używamy składni 'scope: {...} ', w tym przypadku tworzony jest również nowy zakres podrzędny, ale nie dziedziczy on prototypowo od elementu nadrzędnego.) Ogólnie rzecz biorąc, zakres podrzędny powinien być używane z modelem ng, ponieważ tworzysz komponent, który musi wchodzić w interakcje z innymi dyrektywami (np. model ng). Sugeruję więc, abyście poszli z drugim, pracującym, skrzypcowym. –

+0

@MarkRajcok, który nie jest dla mnie opcją, ponieważ dyrektywa jest bardziej skomplikowana i dodaje pewne niestandardowe atrybuty do zakresu, co spowoduje zanieczyszczenie zakresu nadrzędnego –

+0

Ok, użyj 'scope: true', ale także użyj obiektu, nie jest prymitywny: ''. [skrzypce] (http://jsfiddle.net/mrajcok/6ZaB5/). –

Odpowiedz

12

Jak wspomniano w komentarzach, to na ogół nie zaleca się korzystania z zakresu dzieckiem (scope: true lub scope: { ... }) z NG-modelu. Ponieważ jednak Arun musi utworzyć dodatkowe właściwości zakresu, można używać obiektu scope: true z obiektem, a nie z elementem pierwotnym. Ten wykorzystuje prototypowego dziedziczenia, tak $parent nie neeed:

<test-ng-model ng-model="someObj.model" ...> 

fiddle

+0

jest możliwe, aby działał z izolowanym zasięgiem zamiast nowego zakresu http://jsfiddle.net/arunpjohny/gbfNY/1/ –

+0

@ArunPJohny, zakres rodzica nie jest aktualizowany - zauważ, że '{{someObj. model | json}} 'wyjście jest puste. Aby uzyskać więcej informacji o tym, jak nie można mieszać zakresów izolatów i modelu ng, zobacz http://stackoverflow.com/questions/11896732/ngmodel-and-component-with-isolated-scope. –

7

Bo stworzony iso Zasięgiem, ngModel = "model" odnosi się do nowego izolowanego zakresu. Jeśli chcesz odnieść do zakresu AppController, należy użyć $ parent:

<test-ng-model ng-model="$parent.model" name="myel"></test-ng-model> 
+2

'scope: true' nie tworzy zakresu izolowania. –

+0

Dobra uwaga. Moje rozwiązanie i tak by działało, nawet jeśli zakres nie jest izolowany. Ale proponowane rozwiązanie jest o wiele lepsze. –

Powiązane problemy