Qual è la differenza tra & vs @ e = in angularJS


Risposte:


375

@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



1
Grazie per il callout, ho aggiornato la mia risposta con gli URL corretti.
cliff.meyers,

43
È un peccato che la risposta più votata si colleghi ai video dietro una pay wall quando c'è probabilmente un carico di contenuti gratuiti là fuori che contengono le stesse informazioni.
BenCr

Ci sono molti video forniti gratuitamente da egghead :)
Vatsal l'

7
meno uno per i contenuti a pagamento.
Arel Sapir,

109

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:

  1. scope: false: Impostazione predefinita angolare. L'ambito della direttiva è esattamente quello del suo ambito padre ( parentScope).
  2. scope: true: Angular crea un campo di applicazione per questa direttiva. L'ambito eredita prototipicamente da parentScope.
  3. scope: {...}: l'ambito isolato è spiegato di seguito.

La specifica scope: {...}definisce un isolatedScope. An isolatedScopenon 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'.
        },
    }
})

isolatedScopenon 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 è:

inserisci qui la descrizione dell'immagine

@: rilegatura a senso unico

@passa semplicemente la proprietà da parentScopea isolatedScope. Si chiama one-way binding, il che significa che non è possibile modificare il valore delle parentScopeproprietà. Se hai familiarità con l'ereditarietà di JavaScript, puoi comprendere facilmente questi due scenari:

  • Se la proprietà di associazione è di tipo primitivo, come interpolatedPropnell'esempio: è possibile modificarla interpolatedProp, ma parentProp1non verrebbe modificata. Tuttavia, se si modifica il valore di parentProp1, interpolatedPropverrà 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 childScopeaggiornerà anche il valore in parentScopee viceversa. Questa regola funziona sia per primitivi che per oggetti. Se cambi il tipo di associazione di parentObjessere =, scoprirai che puoi modificare il valore di parentObj.x. Un tipico esempio è ngModel.

&: funzione binding

&consente alla direttiva di chiamare alcune parentScopefunzioni 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 valueFromDirectiveviene passata dalla direttiva al controller principale attraverso {valueFromDirective: ....

Riferimento: comprensione degli ambiti


Per impostazione predefinita, le direttive utilizzano l'ambito condiviso. Se la direttiva ha 'scope: true', usa l'ambito ereditato, in cui child può vedere le proprietà parent ma parent non può vedere le proprietà interne child.
YuMei,

1
AngularJS - Scopes isolati - @ vs = vs & ---------- Esempi brevi con spiegazione sono disponibili al seguente link: codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs
Prashanth

24

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:'&'
        }        

17

@ : rilegatura a senso unico

= : associazione a due vie

& : funzione binding


5
un avvertimento importante per @ non è solo la stringa unidirezionale, ma on-way
Shawson,

@Shawson: Quindi come associare la non stringa unidirezionale (es. Int o bool)?
OR Mapper

Se il tuo cuore è impostato su di esso, potresti prendere il valore da @ e cast è su un int / bool? Altrimenti
userei

7

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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.