Jaka jest różnica między & vs @ i = w angularJS

Odpowiedzi:

375

@umożliwia przekazanie wartości zdefiniowanej w atrybucie dyrektywy do izolowanego zakresu dyrektywy. Wartość może być prostą wartością ciągu ( myattr="hello") lub może być ciągiem interpolowanym AngularJS z osadzonymi wyrażeniami ( myattr="my_{{helloText}}"). Potraktuj to jako „jednokierunkową” komunikację z zakresu nadrzędnego do dyrektywy podrzędnej. John Lindquist ma serię krótkich screencastów wyjaśniających każdy z nich. Screencast na @ jest tutaj: https://egghead.io/lessons/angularjs-isolate-scope-attribute-binding

&pozwala zakresowi izolowanemu dyrektywy przekazywać wartości do zakresu nadrzędnego w celu oceny w wyrażeniu zdefiniowanym w atrybucie. Zauważ, że atrybut dyrektywy jest domyślnie wyrażeniem i nie używa składni wyrażenia nawiasów klamrowych. Ten trudniej jest wyjaśnić w tekście. Screencast na temat & jest tutaj: https://egghead.io/lessons/angularjs-isolate-scope-expression-binding

=ustanawia dwukierunkowe wiążące wyrażenie między zakresem izolowania dyrektywy a zakresem nadrzędnym. Zmiany w zakresie potomnym są propagowane do elementu nadrzędnego i odwrotnie. Pomyśl o = jako kombinacji @ i &. Screencast on = is here: https://egghead.io/lessons/angularjs-isolate-scope-two-way-binding

I w końcu tutaj jest screencast, który pokazuje wszystkie trzy użyte razem w jednym widoku: https://egghead.io/lessons/angularjs-isolate-scope-review

cliff.meyers
źródło
1
Dzięki za objaśnienie zaktualizowałem swoją odpowiedź poprawnymi adresami URL.
cliff.meyers
43
Szkoda, że ​​najwyżej oceniana odpowiedź prowadzi do filmów za ścianą płatną, gdy prawdopodobnie jest tam mnóstwo bezpłatnych treści zawierających te same informacje.
BenCr
Egghead
7
minus jeden dla treści płatnych.
Arel Sapir,
109

Chciałbym wyjaśnić pojęcia z perspektywy dziedziczenia prototypów JavaScript. Mam nadzieję, że pomogą zrozumieć.

Istnieją trzy opcje definiowania zakresu dyrektywy:

  1. scope: false: Domyślne kątowe. Zakres dyrektywy jest dokładnie taki, jak jej zakres nadrzędny ( parentScope).
  2. scope: true: Angular tworzy zakres dla tej dyrektywy. Zakres prototypowo dziedziczy parentScope.
  3. scope: {...}: zakres izolowany wyjaśniono poniżej.

Określenie scope: {...}definiuje isolatedScope. isolatedScopeNie dziedziczy właściwości z parentScope, choć isolatedScope.$parent === parentScope. Jest definiowany poprzez:

app.directive("myDirective", function() {
    return {
        scope: {
            ... // defining scope means that 'no inheritance from parent'.
        },
    }
})

isolatedScopenie ma bezpośredniego dostępu do parentScope. Ale czasami dyrektywa musi się komunikować z parentScope. Komunikują się za pośrednictwem @, =i &. Wątek o używaniu symboli @, =a &mówimy o scenariuszach wykorzystującychisolatedScope .

Zwykle jest używany do niektórych popularnych komponentów współdzielonych przez różne strony, takich jak Modały. Izolowany zakres zapobiega zanieczyszczeniu zasięgu globalnego i jest łatwy do dzielenia się między stronami.

Oto podstawowa dyrektywa: http://jsfiddle.net/7t984sf9/5/ . Obraz do zilustrowania to:

wprowadź opis zdjęcia tutaj

@: wiązanie w jedną stronę

@po prostu przekazuje właściwość od parentScopedo isolatedScope. Nazywa się to one-way binding, co oznacza, że ​​nie można modyfikować wartości parentScopewłaściwości. Jeśli znasz dziedziczenie JavaScript, możesz łatwo zrozumieć te dwa scenariusze:

  • Jeśli właściwość wiązania jest typem pierwotnym, tak jak interpolatedPropw przykładzie: można zmodyfikować interpolatedProp, ale parentProp1nie można go zmienić. Jeśli jednak zmienisz wartość parentProp1, interpolatedPropzostanie ona zastąpiona nową wartością (gdy kątowy $ digest).

  • Jeśli właściwość powiązania jest jakimś obiektem, na przykład parentObj: ponieważ ta, do której przekazano, isolatedScopejest odwołaniem, modyfikacja wartości spowoduje wyzwolenie tego błędu:

    TypeError: Cannot assign to read only property 'x' of {"x":1,"y":2}

=: wiązanie dwustronne

=jest wywoływana two-way binding, co oznacza, że ​​każda modyfikacja w childScopespowoduje również aktualizację wartości w parentScopei odwrotnie. Ta reguła działa zarówno dla prymitywów, jak i obiektów. Jeśli zmienisz typ wiązania parentObjna =, przekonasz się, że możesz zmodyfikować wartość parentObj.x. Typowym przykładem jest ngModel.

&: powiązanie funkcji

&pozwala dyrektywie na wywołanie jakiejś parentScopefunkcji i przekazanie pewnej wartości z dyrektywy. Na przykład sprawdź JSFiddle: & w zakresie dyrektywy .

Zdefiniuj klikalny szablon w dyrektywie, taki jak:

<div ng-click="vm.onCheck({valueFromDirective: vm.value + ' is from the directive'})">

I skorzystaj z dyrektywy jak:

<div my-checkbox value="vm.myValue" on-check="vm.myFunction(valueFromDirective)"></div>

Zmienna valueFromDirectivejest przekazywana z dyrektywy do kontrolera nadrzędnego przez {valueFromDirective: ....

Odniesienie: Zrozumienie zakresów

Radość
źródło
Domyślnie dyrektywy używają zakresu wspólnego. Jeśli dyrektywa ma „zasięg: prawda”, wówczas wykorzystuje dziedziczony zakres, w którym dziecko może zobaczyć właściwości rodzica, ale rodzic nie widzi właściwości potomnych.
YuMei,
1
AngularJS - Pojedyncze zakresy - @ vs = vs i ---------- Krótkie przykłady z objaśnieniami są dostępne pod poniższym linkiem: codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs
Prashanth
24

Nie moje skrzypce, ale http://jsfiddle.net/maxisam/QrCXh/ pokazuje różnicę. Kluczowym elementem jest:

           scope:{
            /* NOTE: Normally I would set my attributes and bindings
            to be the same name but I wanted to delineate between 
            parent and isolated scope. */                
            isolatedAttributeFoo:'@attributeFoo',
            isolatedBindingFoo:'=bindingFoo',
            isolatedExpressionFoo:'&'
        }        
jgm
źródło
17

@ : wiązanie w jedną stronę

= : wiązanie dwukierunkowe

& : powiązanie funkcji

Timothy.Li
źródło
5
ważnym zastrzeżeniem dla @ jest nie tylko jednokierunkowy, ale także ciąg znaków w drodze
Shawson
@Shawson: Więc jak powiązać jednokierunkowy non-string (np. Int lub bool)?
LUB Mapper
Jeśli twoje serce jest na nim ustawione, możesz wziąć wartość z @ i rzutować na int / bool? W przeciwnym razie
użyłbym
7

AngularJS - Lunety izolowane - @ vs = vs &


Krótkie przykłady z objaśnieniami są dostępne pod poniższym linkiem:

http://www.codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs

@ - wiążący w jedną stronę

W dyrektywie:

scope : { nameValue : "@name" }

Z uwagi:

<my-widget name="{{nameFromParentScope}}"></my-widget>

= - wiązanie dwukierunkowe

W dyrektywie:

scope : { nameValue : "=name" },
link : function(scope) {
  scope.name = "Changing the value here will get reflected in parent scope value";
}

Z uwagi:

<my-widget name="{{nameFromParentScope}}"></my-widget>

& - Wywołanie funkcji

W dyrektywie:

scope : { nameChange : "&" }
link : function(scope) {
  scope.nameChange({newName:"NameFromIsolaltedScope"});
}

Z uwagi:

<my-widget nameChange="onNameChange(newName)"></my-widget>
Prashanth
źródło
5

Zajęło mi naprawdę dużo czasu, aby naprawdę się z tym pogodzić. Kluczem do mnie było zrozumienie, że „@” dotyczy rzeczy, które chcesz ocenić in situ i które zostały przekazane do dyrektywy jako stała, gdzie „=” faktycznie przekazuje sam obiekt.

Jest ładny post na blogu, który wyjaśnia to na: http://blog.ramses.io/technical/AngularJS-the-difference-between-@-&-and-=-when-declaring-directives-using-isolate-scopes

Peter Nixey
źródło