javascript - diferencias - ¿Cuál es la diferencia entre & vs @ y=en angularJS
diferencia entre angularjs y angular2 (6)
Soy muy nuevo en AngularJS. ¿Alguien puede explicarme la diferencia entre estos operadores AngularJS: &, @ and =
al aislar el alcance con el ejemplo adecuado?
Me gustaría explicar los conceptos desde la perspectiva de la herencia del prototipo de JavaScript. Esperemos que ayude a entender.
Hay tres opciones para definir el alcance de una directiva:
-
scope: false
: por defecto angular. El alcance de la directiva es exactamente el de su alcance principal (parentScope
). -
scope: true
: Angular crea un ámbito para esta directiva. El alcance se hereda prototípicamente deparentScope
. -
scope: {...}
: el alcance aislado se explica a continuación.
Especificando el scope: {...}
define un isolatedScope
. Un isolatedScope
no hereda las propiedades de parentScope
, aunque isolatedScope.$parent === parentScope
. Se define a través de:
app.directive("myDirective", function() {
return {
scope: {
... // defining scope means that ''no inheritance from parent''.
},
}
})
isolatedScope
no tiene acceso directo a parentScope
. Pero a veces la directiva necesita comunicarse con el parentScope
. Se comunican a través de @
, =
y &
. El tema sobre el uso de los símbolos @
, =
y &
están hablando de escenarios utilizando isolatedScope
.
Normalmente se usa para algunos componentes comunes compartidos por diferentes páginas, como los Modales. Un alcance aislado evita la contaminación del alcance global y es fácil de compartir entre páginas.
Aquí hay una directiva básica: http://jsfiddle.net/7t984sf9/5/ . Una imagen para ilustrar es:
@
: encuadernación unidireccional
@
simplemente pasa la propiedad de parentScope
a isolatedScope
. Se denomina one-way binding
, lo que significa que no puede modificar el valor de parentScope
propiedades de parentScope
. Si está familiarizado con la herencia de JavaScript, puede comprender estos dos escenarios fácilmente:
Si la propiedad de enlace es un tipo primitivo, como
interpolatedProp
en el ejemplo: puede modificarinterpolatedProp
, peroparentProp1
no se cambiaría. Sin embargo, si cambia el valor deparentProp1
,interpolatedProp
se sobrescribirá con el nuevo valor (cuando angular $ digest).Si la propiedad de enlace es algún objeto, como
parentObj
: dado que la que se pasó aisolatedScope
es una referencia, la modificación del valor generará este error:TypeError: Cannot assign to read only property ''x'' of {"x":1,"y":2}
=
: enlace de dos vías
=
se llama two-way binding
, lo que significa que cualquier modificación en childScope
también actualizará el valor en parentScope
, y viceversa. Esta regla funciona tanto para primitivos como para objetos. Si cambia el tipo de parentObj
de parentObj
a ser =
, encontrará que puede modificar el valor de parentObj.x
. Un ejemplo típico es ngModel
.
&
: enlace de funciones
&
permite que la directiva llame a alguna función parentScope
y pase algún valor de la directiva. Por ejemplo, verifique JSFiddle: & en el ámbito de la directiva .
Defina una plantilla pulsable en la directiva como:
<div ng-click="vm.onCheck({valueFromDirective: vm.value + '' is from the directive''})">
Y usa la directiva como:
<div my-checkbox value="vm.myValue" on-check="vm.myFunction(valueFromDirective)"></div>
La variable valueFromDirective
se pasa de la directiva al controlador principal a través de {valueFromDirective: ...
Referencia: Entendiendo los alcances
Me tomó muchísimo tiempo realmente entender esto. La clave para mí fue entender que "@" es para las cosas que desea evaluar in situ y pasar a la directiva como una constante donde "=" en realidad pasa el objeto en sí.
Hay una buena publicación en el blog que explica esto en: http://blog.ramses.io/technical/AngularJS-the-difference-between-@-&-and-=-when-declaring-directives-using-isolate-scopes
No es mi violín, pero http://jsfiddle.net/maxisam/QrCXh/ muestra la diferencia. La pieza clave es:
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:''&''
}
@
permite que un valor definido en el atributo de directiva se pase al ámbito de aislamiento de la directiva. El valor podría ser un valor de cadena simple ( myattr="hello"
) o podría ser una cadena interpolada AngularJS con expresiones incrustadas ( myattr="my_{{helloText}}"
). Piense en ello como una comunicación "unidireccional" del ámbito principal a la directiva secundaria. John Lindquist tiene una serie de screencasts cortos que explican cada uno de estos. Screencast en @ está aquí: https://egghead.io/lessons/angularjs-isolate-scope-attribute-binding
&
permite que el ámbito de aislamiento de la directiva pase valores al ámbito principal para evaluación en la expresión definida en el atributo. Tenga en cuenta que el atributo de directiva es implícitamente una expresión y no utiliza la sintaxis de expresión de corsé doble. Esta es más difícil de explicar en el texto. Screencast en y está aquí: https://egghead.io/lessons/angularjs-isolate-scope-expression-binding
=
configura una expresión de enlace bidireccional entre el ámbito de aislamiento de la directiva y el ámbito primario. Los cambios en el ámbito hijo se propagan al padre y viceversa. Piense en = como una combinación de @ y &. Screencast on = está aquí: https://egghead.io/lessons/angularjs-isolate-scope-two-way-binding
Y finalmente, aquí hay un screencast que muestra los tres utilizados juntos en una sola vista: https://egghead.io/lessons/angularjs-isolate-scope-review
@ : encuadernación unidireccional
= : enlace de dos vías
& : enlace de funciones
AngularJS - Scopes aislados - @ vs = vs &
Los ejemplos cortos con explicación están disponibles en el siguiente enlace:
codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs
@ - enlace unidireccional
En la directiva:
scope : { nameValue : "@name" }
En vista:
<my-widget name="{{nameFromParentScope}}"></my-widget>
= - enlace de dos vías
En la directiva:
scope : { nameValue : "=name" },
link : function(scope) {
scope.name = "Changing the value here will get reflected in parent scope value";
}
En vista:
<my-widget name="{{nameFromParentScope}}"></my-widget>
& - Llamada de función
En la directiva:
scope : { nameChange : "&" }
link : function(scope) {
scope.nameChange({newName:"NameFromIsolaltedScope"});
}
En vista:
<my-widget nameChange="onNameChange(newName)"></my-widget>