2013-02-23 15 views
5

Właśnie znalazł ciekawe pozorną niespójność, co jest dozwolone w wyrażeniach kątowe:Dlaczego przypisanie nie zawsze działa w wyrażeniach kątowych?

  1. Jest możliwe, aby wykonać zadanie w wyrażeniu
  2. To łamie jeśli zadanie polega na zmienną lokalną z ngRepeat
  3. Problem ten rozwiązać można za pomocą ustawiającej zdefiniowany w sterowniku zamiast przypisania w wyrażeniu

See Plunker

Wydaje się, że docs on expressions jawnie blokuje przepływ sterowania w wyrażeniach i nie widzę żadnej wzmianki o takim zachowaniu powyżej.

Przypuszczam, że na wynos z tego powodu jest prawdopodobnie lepszym wzorcem do wykorzystania setera, ale czy ktoś wie o bardziej precyzyjnym odwołaniu się do tego, co jest możliwe w wyrażeniach?

Może byłoby lepiej, gdyby Angular jednostronnie zabronił wykonywania zadań. (Powiązana niespójność polega na tym, że możliwe jest zwiększenie wyrażenia za pomocą i = i + 1, ale nie za pomocą i + = 1 ...).

Odpowiedz

11

Jest to znany problem z zakresu w dyrektywach. Możesz przeczytać artykuł The Nuances of Scope Prototypal Inheritance, aby dowiedzieć się więcej o scoping w kątowym js.

Wszelkie prymitywny przyporządkowanie wartości od dziecka/dołączany zakresu stworzy nową wartość instancji zamiast zmieniać zakresy macierzyste cenią

W twoim przypadku pracy z wartości pierwotnej selectedNumber.

Istnieją dwa sugerowane sposoby Fix

Rozwiązanie 1
użyć obiektu zamiast wartości pierwotnej.

  1. Zmień selectedNumber do obiektu scope.selectedNumber = { num : 1 };
  2. Change display do <h2>{{ selectedNumber.num }}</h2>
  3. Zmiana obsługi kliknięcie w ng-repeat do ng-click="selectedNumber.num = number"

Demo: Plunker

Rozwiązanie 2:
Zastosowanie $parent odniesienia zakres

  1. Zmiana obsługi kliknięcie w ng-repeat do ng-click="$parent.selectedNumber = number"

Demo: Plunker

Rozwiązanie 3:
Użyj seter w zakresie dominującej

  1. Tworzenie metody setter w zakresie dominującej jak $scope.setSelectedNumber = function(num){ $scope.selectedNumber = num}
  2. Zmian zdarzenie kliknij aby setSelectedNumber(number) (jest to metoda już wykorzystane)

Aktualizacja:
Jak sugeruje Andersa Ekdahl, zaleca się użycie rozwiązania opartego na obiekcie (rozwiązanie 1).

+1

Powinieneś używać obiektu jako modelu zamiast uzyskiwania dostępu do zakresu nadrzędnego przez $ parent. Uzyskanie dostępu do $ parent prowadzi do kruchego kodu, ponieważ przestanie działać, jeśli dodamy inny zakres pomiędzy. –

+0

@AndersEkdahl masz rację, właśnie podałem dostępne opcje jako odpowiedź, w artykule na temat wskaźnika wyjaśniono przypadki użycia i problemy: –

+0

Awesome! Dzięki za szybką odpowiedź! To ma sens. FYI, prawdziwym przypadkiem użycia dla tego jest dynamiczne wybieranie tła strony w edytorze stron na podstawie tablicy podglądu "próbki". Ustawiana wartość nazywa się "selectedClass", ale jest ciągiem znaków, więc domyślam się, że nadal jest typem pierwotnym i dotyczy tego samego problemu. Choć niesamowite jest, aby zobaczyć swoje rozwiązania, czy uważasz, że seter w kontrolerze byłby lepszym projektem? – bellkev

Powiązane problemy