2013-03-13 7 views
33

Ja próbuje zaktualizować mojego modelu przy użyciu ng-click dołączony do <p>.Zachowanie wyrażenia przypisania wywoływanego przez ng kliknij ciągu ng-powtórzyć

, że nie ma problemu z wyrażeniem przypisania poza wystąpienia ng-repeat, lub wywoływania sposób zakres wewnątrzng-repeat. Jednak jeśli użyję przypisania wng-repeat, wydaje się być zignorowane. Nie widzę żadnych komunikatów zgłaszanych w konsoli Firefox, ale nie próbowałem ustawiać punktów przerwania, aby sprawdzić, czy zdarzenie jest uruchamiane.

<!DOCTYPE html> 
<html> 
<head> 
    <title>Test of ng-click</title> 
    <script type='text/javascript' src='http://code.angularjs.org/1.1.1/angular.js'></script> 
    <script type='text/javascript'>//<![CDATA[ 

     function MyCtrl($scope) { 
      $scope.selected = ""; 
      $scope.defaultValue = "test"; 
      $scope.values = ["foo", "bar", "baz"]; 

      $scope.doSelect = function(val) { 
       $scope.selected = val; 
      } 
     } 
     //]]> 

    </script> 
</head> 

<body ng-app> 
    <div ng-controller='MyCtrl'> 
     <p>Selected = {{selected}}</p> 
     <hr/> 
     <p ng-click='selected = defaultValue'>Click me</p> 
     <hr/> 
     <p ng-repeat='value in values' ng-click='selected = value'>{{value}}</p> 
     <hr/> 
     <p ng-repeat='value in values' ng-click='doSelect(value)'>{{value}}</p> 
    </div> 
</body> 
</html> 

Fiddle jest here, jeśli wolisz (wraz z kilkoma wcześniejszymi wariantami).

Odpowiedz

78

dyrektywa ngRepeat stwarza nowe możliwości dla każdej iteracji, więc trzeba odwołać się zmienne w zakresie dominującej.

Zastosowanie $parent.selected = value, jak w:

<p ng-repeat='value in values' ng-click='$parent.selected = value'>{{value}}</p> 

Uwaga: Wywołanie funkcji propaguje powodu prototypal dziedziczenia.

Jeśli chcesz dowiedzieć się więcej: The Nuances of Scope Prototypal Inheritance.

+2

D'oh! Wiedziałem, że musi to być coś prostego. – kdgregory

+4

+1. Chociaż $ rodzic będzie działał, zalecane jest użycie obiektu dla twojego modelu (zobacz moją odpowiedź po więcej szczegółów). –

20

Jak wspomniano @Stewie, $ rodzic jest jednym ze sposobów, aby rozwiązać ten problem. Jednak zalecanym (by the Angular team) rozwiązaniem jest nie definiowanie prymitywnych właściwości w $ scope. Zamiast tego zakres $ powinien odnosić się do twojego modelu. Używanie odniesień pozwala również uniknąć problemu (ponieważ prymitywne właściwości nie zostaną utworzone w zakresach potomnych, które ukrywają/zacieniają właściwości nadrzędnego zakresu o tej samej nazwie), i nie trzeba pamiętać, kiedy należy użyć $ parent:

HTML:

<p>Selected = {{model.selected}}</p> 
<hr/> 
<p ng-click='model.selected = defaultValue'>Click me</p> 
<hr/> 
<p ng-repeat='value in values' ng-click='model.selected = value'>{{value}}</p> 
<hr/> 
<p ng-repeat='value in values' ng-click='doSelect(value)'>{{value}}</p> 

JavaScript:

$scope.model = { selected: ""}; 
... 
$scope.doSelect = function (val) { 
    $scope.model.selected = val; 
} 

Fiddle.

ja niedawno zaktualizował stronę wiki że @Stewie wspomniał zawsze polecam tego podejścia.

+0

+1 Zgadzam się. Używanie $ parent zawsze wydaje się nieco hackish, mimo że efekt końcowy jest taki sam. Nawet go nie używam. Chyba byłem trochę zbyt leniwy, żeby wyjaśnić ".". +1 za aktualizację wiki. – Stewie

+1

Muszę powiedzieć, że uważam stworzenie specjalnego obiektu "modelu" za bardziej hackowy. I bardziej prawdopodobne, że doprowadzi to do błędów na złożonej stronie (od błędów pisowni, jeśli nic więcej). Osobiście uważam, że funkcje są najlepszym rozwiązaniem do aktualizacji modeli (a także do wyrażeń w 'ng-show' i tym podobnych). – kdgregory

+0

@kdgregory "Celem zakresu $ jest * odwołanie * do modelu, a nie * bycie * modelem" (z filmu zespołu Angular, o którym wspomniał Mark). Możesz użyć dowolnego obiektu javascript, który ma być modelem, a następnie połączyć go z zakresem. – antoine