Risposte:
@
consente a un valore definito nell'attributo direttiva di essere passato all'ambito di isolamento della direttiva. Il valore potrebbe essere un semplice valore stringa ( myattr="hello"
) oppure potrebbe essere una stringa interpolata AngularJS con espressioni incorporate ( myattr="my_{{helloText}}"
). Consideralo come una comunicazione "unidirezionale" dall'ambito genitore alla direttiva figlio. John Lindquist ha una serie di brevi screencast che spiegano ciascuno di questi. Screencast su @ è qui: https://egghead.io/lessons/angularjs-isolate-scope-attribute-binding
&
consente all'ambito di isolamento della direttiva di passare valori nell'ambito padre per la valutazione nell'espressione definita nell'attributo. Si noti che l'attributo direttiva è implicitamente un'espressione e non utilizza la sintassi dell'espressione parentesi graffa doppia. Questo è più difficile da spiegare nel testo. Screencast on & is here: https://egghead.io/lessons/angularjs-isolate-scope-expression-binding
=
imposta un'espressione vincolante a due vie tra l'ambito di isolamento della direttiva e l'ambito padre. Le modifiche all'ambito figlio vengono propagate al genitore e viceversa. Pensa a = come una combinazione di @ e &. Screencast on = è qui: https://egghead.io/lessons/angularjs-isolate-scope-two-way-binding
E finalmente ecco uno screencast che mostra tutti e tre usati insieme in un'unica vista: https://egghead.io/lessons/angularjs-isolate-scope-review
Vorrei spiegare i concetti dal punto di vista dell'ereditarietà del prototipo JavaScript. Spero che aiuti a capire.
Esistono tre opzioni per definire l'ambito di una direttiva:
scope: false
: Impostazione predefinita angolare. L'ambito della direttiva è esattamente quello del suo ambito padre ( parentScope
).scope: true
: Angular crea un campo di applicazione per questa direttiva. L'ambito eredita prototipicamente da parentScope
.scope: {...}
: l'ambito isolato è spiegato di seguito. La specifica scope: {...}
definisce un isolatedScope
. An isolatedScope
non eredita le proprietà da parentScope
, sebbene isolatedScope.$parent === parentScope
. È definito attraverso:
app.directive("myDirective", function() {
return {
scope: {
... // defining scope means that 'no inheritance from parent'.
},
}
})
isolatedScope
non ha accesso diretto a parentScope
. Ma a volte la direttiva deve comunicare con parentScope
. Essi comunicano attraverso @
, =
e &
. L'argomento sull'utilizzo di simboli @
, =
e &
si parla di scenari che utilizzanoisolatedScope
.
Di solito viene utilizzato per alcuni componenti comuni condivisi da pagine diverse, come Modali. Un ambito isolato impedisce di inquinare l'ambito globale ed è facile da condividere tra le pagine.
Ecco una direttiva di base: http://jsfiddle.net/7t984sf9/5/ . Un'immagine da illustrare è:
@
: rilegatura a senso unico@
passa semplicemente la proprietà da parentScope
a isolatedScope
. Si chiama one-way binding
, il che significa che non è possibile modificare il valore delle parentScope
proprietà. Se hai familiarità con l'ereditarietà di JavaScript, puoi comprendere facilmente questi due scenari:
Se la proprietà di associazione è di tipo primitivo, come interpolatedProp
nell'esempio: è possibile modificarla interpolatedProp
, ma parentProp1
non verrebbe modificata. Tuttavia, se si modifica il valore di parentProp1
, interpolatedProp
verrà sovrascritto con il nuovo valore (quando angolare $ digest).
Se la proprietà di associazione è un oggetto, ad esempio parentObj
: poiché quello passato a isolatedScope
è un riferimento, la modifica del valore attiverà questo errore:
TypeError: Cannot assign to read only property 'x' of {"x":1,"y":2}
=
: rilegatura a due vie=
viene chiamato two-way binding
, il che significa che qualsiasi modifica in childScope
aggiornerà anche il valore in parentScope
e viceversa. Questa regola funziona sia per primitivi che per oggetti. Se cambi il tipo di associazione di parentObj
essere =
, scoprirai che puoi modificare il valore di parentObj.x
. Un tipico esempio è ngModel
.
&
: funzione binding&
consente alla direttiva di chiamare alcune parentScope
funzioni e passare un certo valore dalla direttiva. Ad esempio, selezionare JSFiddle: & nell'ambito della direttiva .
Definire un modello cliccabile nella direttiva come:
<div ng-click="vm.onCheck({valueFromDirective: vm.value + ' is from the directive'})">
E usa la direttiva come:
<div my-checkbox value="vm.myValue" on-check="vm.myFunction(valueFromDirective)"></div>
La variabile valueFromDirective
viene passata dalla direttiva al controller principale attraverso {valueFromDirective: ...
.
Riferimento: comprensione degli ambiti
Non il mio violino, ma http://jsfiddle.net/maxisam/QrCXh/ mostra la differenza. Il pezzo chiave è:
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:'&'
}
@ : rilegatura a senso unico
= : associazione a due vie
& : funzione binding
AngularJS - Mirini isolati - @ vs = vs &
Brevi esempi con spiegazione sono disponibili al seguente link:
http://www.codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs
@ - rilegatura a senso unico
In direttiva:
scope : { nameValue : "@name" }
In vista:
<my-widget name="{{nameFromParentScope}}"></my-widget>
= - associazione a due vie
In direttiva:
scope : { nameValue : "=name" },
link : function(scope) {
scope.name = "Changing the value here will get reflected in parent scope value";
}
In vista:
<my-widget name="{{nameFromParentScope}}"></my-widget>
& - Chiamata di funzione
In direttiva:
scope : { nameChange : "&" }
link : function(scope) {
scope.nameChange({newName:"NameFromIsolaltedScope"});
}
In vista:
<my-widget nameChange="onNameChange(newName)"></my-widget>
Mi ci è voluto un sacco di tempo per capire davvero questo. La chiave per me era capire che "@" è per cose che vuoi valutare in situ e passate attraverso la direttiva come una costante in cui "=" passa effettivamente l'oggetto stesso.
C'è un bel post sul blog che spiega questo a: http://blog.ramses.io/technical/AngularJS-the-difference-between-@-&-and-=-when-declaring-directives-using-isolate-scopes