Leí cuidadosamente la documentación de AngularJS sobre el tema, y luego jugueteé con una directiva. Aquí está el violín .
Y aquí hay algunos fragmentos relevantes:
Del HTML :
<pane bi-title="title" title="{{title}}">{{text}}</pane>
De la directiva del panel:
scope: { biTitle: '=', title: '@', bar: '=' },
Hay varias cosas que no entiendo:
- ¿Por qué tengo que usar
"{{title}}"
con'@'
y"title"
con'='
? - ¿Puedo acceder directamente al ámbito principal directamente, sin decorar mi elemento con un atributo?
- La documentación dice "A menudo es deseable pasar datos del ámbito aislado a través de la expresión y al ámbito primario" , pero eso parece funcionar bien con el enlace bidireccional también. ¿Por qué la ruta de expresión sería mejor?
Encontré otro violín que también muestra la solución de expresión: http://jsfiddle.net/maxisam/QrCXh/
=
se utiliza en el alcance de aislamiento de la directiva para habilitar el enlace bidireccional y@
no actualiza el modelo, solo actualiza los valores del alcance de la Directiva.Respuestas:
@ vincula una propiedad de alcance local / directiva al valor evaluado del atributo DOM . Si usa
title=title1
otitle="title1"
, el valor del atributo DOM "título" es simplemente la cadenatitle1
. Si lo usatitle="{{title}}"
, el valor del atributo DOM "título" es el valor interpolado de{{title}}
, por lo tanto, la cadena será la propiedad de ámbito principal "título" actualmente establecida. Como los valores de los atributos son siempre cadenas, siempre terminará con un valor de cadena para esta propiedad en el alcance de la directiva cuando use @ .= vincula una propiedad de ámbito local / directiva a una propiedad de ámbito principal . Entonces, con = , usa el nombre de la propiedad modelo / alcance principal como el valor del atributo DOM. No puedes usar
{{}}
s con = .Con @, puede hacer cosas como
title="{{title}} and then some"
: {{title}} se interpola, luego la cadena "y algunos" se concatena con ella. La cadena final concatenada es lo que obtiene la propiedad de ámbito local / directiva. (No puede hacer esto con = , solo @ .)Con @ , deberá usarlo
attr.$observe('title', function(value) { ... })
si necesita usar el valor en su función de enlace (ing). Por ejemplo,if(scope.title == "...")
no funcionará como esperabas. Tenga en cuenta que esto significa que solo puede acceder a este atributo de forma asincrónica . No necesita usar $ observe () si solo está usando el valor en una plantilla. Ejtemplate: '<div>{{title}}</div>'
.Con = , no necesita usar $ observe.
Sí, pero solo si no utiliza un alcance aislado. Eliminar esta línea de su directiva
scope: { ... }
y luego su directiva no creará un nuevo alcance. Utilizará el ámbito principal. Luego puede acceder a todas las propiedades del ámbito primario directamente.
Sí, el enlace bidireccional permite que el ámbito local / directivo y el ámbito primario compartan datos. El "enlace de expresión" permite que la directiva invoque una expresión (o función) definida por un atributo DOM, y también puede pasar datos como argumentos a la expresión o función. Por lo tanto, si no necesita compartir datos con el padre (solo desea llamar a una función definida en el ámbito primario), puede usar la sintaxis & .
Ver también
fuente
@
('at') copia el valor del 'Atributo'.=
('igual') es equivalente a decir que la clave es igual a su expresión. Así, al menos, así es como los mantengo firmes.foo="{{1+1}}"
, porque no necesitamos enlace de datos bidireccional aquí. El punto que intenté hacer en el comentario anterior es que deberíamos usar = solo cuando la directiva necesita enlace de datos bidireccional. Use @ o & de lo contrario.Hay un montón de grandes respuestas aquí, pero me gustaría ofrecer mi punto de vista sobre las diferencias entre
@
,=
y&
vinculante que demostrado ser útil para mí.Los tres enlaces son formas de pasar datos desde su ámbito principal al ámbito aislado de su directiva a través de los atributos del elemento:
Creo que es más fácil recordar estas diferencias al referirme a los enlaces de alcance con una descripción más corta:
@
Enlace de cadena de atributo=
Encuadernación de modelo bidireccional&
Enlace de método de devolución de llamadaLos símbolos también aclaran qué representa la variable de alcance dentro de la implementación de su directiva:
@
cuerda=
modelo&
métodoEn orden de utilidad (para mí de todos modos):
fuente
"&"
admite argumentos (o, más bien, locales) de la forma:,callback({foo: "some value"})
que luego podrían usarse<my-dir callback="doSomething(foo)">
. De lo contrario, buena respuestacallback(argument)
. Que todavía no es lo mismo quecallback
sí mismo.Los
=
medios de unión bi-direccional, por lo que una referencia a una variable con el alcance de los padres. Esto significa que, cuando cambia la variable en la directiva, también cambiará en el ámbito primario.@
significa que la variable se copiará (clonará) en la directiva.Que yo sepa,
<pane bi-title="{{title}}" title="{{title}}">{{text}}</pane>
debería funcionar también.bi-title
recibirá el valor de la variable de ámbito principal, que se puede cambiar en la directiva.Si necesita cambiar varias variables en el ámbito primario, puede ejecutar una función en el ámbito primario desde la directiva (o pasar datos a través de un servicio).
fuente
Si desea ver más cómo funciona esto con un ejemplo en vivo. http://jsfiddle.net/juanmendez/k6chmnch/
fuente
@
llegar como una cuerda=
Unión de 2 vías&
Esto se comporta de manera un poco diferente, porque el ámbito obtiene una función que devuelve el objeto que se pasó . Supongo que esto fue necesario para que funcione. El violín debe dejar esto claro.Este violín debe demostrar cómo funcionan . Preste especial atención a las funciones de alcance con
get...
el nombre para comprender mejor lo que quiero decir sobre&
fuente
Hay tres formas en que se puede agregar alcance en la directiva:
El alcance de la directiva y su padre (controlador / directiva dentro del cual se encuentra) es el mismo. Por lo tanto, cualquier cambio realizado en las variables de ámbito dentro de la directiva también se refleja en el controlador principal. No necesita especificar esto, ya que es el predeterminado.
Aquí, si cambia las variables de alcance dentro de la directiva, no se reflejará en el alcance primario, pero si cambia la propiedad de una variable de alcance, eso se refleja en el alcance primario, ya que realmente modificó la variable de alcance del padre .
Ejemplo,
Esto sucede cuando está creando complementos, ya que esto hace que la directiva sea genérica, ya que se puede colocar en cualquier HTML y no se ve afectada por su ámbito principal.
Ahora, si no desea ninguna interacción con el ámbito principal, puede especificar el ámbito como un objeto vacío. me gusta,
En general, este no es el caso, ya que necesitamos cierta interacción con el ámbito principal, por lo que queremos que se transmitan algunos de los valores / cambios. Por esta razón, utilizamos:
@ significa que los cambios desde el alcance del controlador se reflejarán en el alcance de la directiva, pero si modifica el valor en el alcance de la directiva, la variable del alcance del controlador no se verá afectada.
@ siempre espera que el atributo asignado sea una expresión. Esto es muy importante; porque para que el prefijo "@" funcione, debemos ajustar el valor del atributo dentro de {{}}.
= es bidireccional, por lo que si cambia la variable en el alcance de la directiva, la variable del alcance del controlador también se ve afectada
& se usa para vincular el método de alcance del controlador para que, si es necesario, podamos llamarlo desde la directiva
La ventaja aquí es que el nombre de la variable no necesita ser el mismo en el alcance del controlador y el alcance de la directiva.
Ejemplo, el alcance de la directiva tiene una variable "dirVar" que se sincroniza con la variable "contVar" del alcance del controlador. Esto le da mucha potencia y generalización a la directiva, ya que un controlador puede sincronizarse con la variable v1, mientras que otro controlador que usa la misma directiva puede pedirle a dirVar que se sincronice con la variable v2.
A continuación se muestra el ejemplo de uso:
La directiva y el controlador son:
Y el html (tenga en cuenta la diferencia para @ y =):
Aquí hay un enlace al blog que lo describe muy bien.
fuente
Simplemente podemos usar: -
@ : - para valores de cadena para enlace de datos unidireccional. de una manera, el enlace de datos solo puede pasar el valor del alcance a la directiva
= : - para el valor del objeto para el enlace de datos bidireccional. en el enlace de datos de dos vías, puede cambiar el valor del alcance en la directiva, así como también en html.
& : - para métodos y funciones.
EDITAR
En nuestra definición de Componente para la versión angular 1.5 Y arriba,
hay cuatro tipos diferentes de enlaces:
=
Enlace de datos bidireccional : si cambiamos el valor, se actualizará automáticamente<
enlace unidireccional : cuando solo queremos leer un parámetro de un ámbito primario y no actualizarlo.@
esto es para parámetros de cadena&
esto es para devoluciones de llamada en caso de que su componente necesite generar algo en su ámbito primariofuente
Creé un pequeño archivo HTML que contiene código angular que demuestra las diferencias entre ellos:
fuente
El = camino es un enlace bidireccional , que le permite tener cambios en vivo dentro de su directiva. Cuando alguien cambia esa variable fuera de la directiva, tendrá esos datos modificados dentro de su directiva, pero @ way no es un enlace bidireccional . Funciona como texto . Atas una vez y solo tendrás su valor.
Para tenerlo más claro, puedes usar este excelente artículo:
Ámbito de la directiva AngularJS '@' y '='
fuente
Esta pregunta ya ha sido golpeada hasta la muerte, pero la compartiré de todos modos en caso de que alguien más esté luchando con el horrible desastre que es el alcance de AngularJS. Esta cubierta
=
,<
,@
,&
y::
. La redacción completa se puede encontrar aquí .=
establece un enlace bidireccional. Cambiar la propiedad en el padre dará como resultado un cambio en el hijo, y viceversa.<
establece un enlace unidireccional, de padre a hijo. Cambiar la propiedad en el padre dará como resultado un cambio en el hijo, pero cambiar la propiedad del hijo no afectará la propiedad del padre.@
asignará a la propiedad secundaria el valor de cadena del atributo de etiqueta. Si el atributo contiene una expresión , la propiedad secundaria se actualiza cada vez que la expresión se evalúa en una cadena diferente. Por ejemplo:Aquí, la
description
propiedad en el ámbito secundario será el valor actual de la expresión"The movie title is {{$ctrl.movie.title}}"
, dondemovie
es un objeto en el ámbito primario.&
es un poco complicado, y de hecho no parece haber ninguna razón convincente para usarlo. Le permite evaluar una expresión en el ámbito primario, sustituyendo parámetros con variables del ámbito secundario. Un ejemplo ( plunk ):Dado
parentVar=10
, la expresiónparentFoo({myVar:5, myOtherVar:'xyz'})
se evaluará5 + 10 + 'xyz'
y el componente se representará como:¿Cuándo querrías usar esta funcionalidad enrevesada?
&
A menudo la gente lo utiliza para pasar al ámbito secundario una función de devolución de llamada en el ámbito primario. En realidad, sin embargo, se puede lograr el mismo efecto usando '<' para pasar la función, que es más sencilla y evita la incómoda sintaxis de llaves para pasar parámetros ({myVar:5, myOtherVar:'xyz'}
). Considerar:Devolución de llamada utilizando
&
:Devolución de llamada utilizando
<
:Tenga en cuenta que los objetos (y las matrices) se pasan por referencia al ámbito secundario, no se copian. Lo que esto significa es que, incluso si se trata de un enlace unidireccional, está trabajando con el mismo objeto en el ámbito primario y secundario.
Para ver los diferentes prefijos en acción, abra este plunk .
Enlace único (inicialización) usando::
[Documentos oficiales]
Las versiones posteriores de AngularJS introducen la opción de tener un enlace de una sola vez, donde la propiedad del ámbito secundario se actualiza solo una vez. Esto mejora el rendimiento al eliminar la necesidad de vigilar la propiedad principal. La sintaxis es diferente de la anterior; para declarar un enlace de una sola vez, agregue
::
delante de la expresión en la etiqueta del componente :Esto propagará el valor del
tagline
ámbito secundario sin establecer un enlace unidireccional o bidireccional. Nota : sitagline
está inicialmenteundefined
en el ámbito primario, angular lo observará hasta que cambie y luego realizará una actualización única de la propiedad correspondiente en el ámbito secundario.Resumen
La siguiente tabla muestra cómo funcionan los prefijos dependiendo de si la propiedad es un objeto, matriz, cadena, etc.
fuente
La propiedad @ alcance local se utiliza para acceder a los valores de cadena que se definen fuera de la directiva.
= En los casos en que necesite crear un enlace bidireccional entre el alcance externo y el alcance aislado de la directiva, puede usar el carácter =.
Y propiedad de ámbito local permite al consumidor de una directiva pasar una función que la directiva puede invocar.
Compruebe amablemente el siguiente enlace que le brinda una comprensión clara con ejemplos. Me pareció muy útil, así que pensé en compartirlo.
http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-2-isolate-scope
fuente
Incluso cuando el ámbito es local, como en su ejemplo, puede acceder al ámbito primario a través de la propiedad
$parent
. Suponga en el siguiente código, quetitle
se define en el ámbito primario. Luego puede acceder al título como$parent.title
:Sin embargo, en la mayoría de los casos, el mismo efecto se obtiene mejor utilizando atributos.
Un ejemplo de dónde encontré la notación "&", que se usa "para pasar datos del ámbito aislado a través de una expresión y al ámbito primario", útil (y no se pudo utilizar un enlace de datos bidireccional) estaba en una directiva para representar una estructura de datos especial dentro de una repetición ng.
Una parte de la representación fue un botón de eliminación y aquí fue útil adjuntar una función de eliminación desde el ámbito externo a través de &. Dentro de la directiva de renderización parece
La vinculación de datos bidireccional, es decir
data = "="
, no se puede utilizar, ya que la función de eliminación se ejecutaría en cada$digest
ciclo, lo que no es bueno, ya que el registro se elimina inmediatamente y nunca se procesa.fuente
Implementé todas las opciones posibles en un violín.
Se ocupa de todas las opciones:
https://jsfiddle.net/rishulmatta/v7xf2ujm
fuente
la principal diferencia entre ellos es solo
fuente
@
y=
ver otras respuestas.Uno se equivocó sobre TL; DR; obtiene la expresión (no solo función como en los ejemplos en otras respuestas) de un padre, y la establece como una función en la directiva, que llama a la expresión. Y esta función tiene la capacidad de reemplazar cualquier variable (incluso el nombre de la función) de expresión, pasando un objeto con las variables.
&
&
explicado
&
es una referencia de expresión, eso significa que si pasa algo como<myDirective expr="x==y"></myDirective>
en la directiva, esta
expr
será una función, que llama a la expresión, como:function expr(){return x == y}
.entonces, en la directiva, html
<button ng-click="expr()"></button>
llamará a la expresión. En js de la directiva solo$scope.expr()
llamaremos a la expresión también.Se llamará a la expresión con $ scope.x y $ scope.y del padre.
¡Tienes la capacidad de anular los parámetros!
Si los configura por llamada, por ejemplo
<button ng-click="expr({x:5})"></button>
, la expresión se llamará con su parámetro
x
y el parámetro principaly
.Puedes anular ambos.
Ahora ya sabes, por qué
<button ng-click="functionFromParent({x:5})"></button>
funciona.Porque solo llama a la expresión de padre (p. Ej.
<myDirective functionFromParent="function1(x)"></myDirective>
) y reemplaza los posibles valores con los parámetros especificados, en este casox
.podría ser:
<myDirective functionFromParent="function1(x) + 5"></myDirective>
o
<myDirective functionFromParent="function1(x) + z"></myDirective>
con el llamado niño:
<button ng-click="functionFromParent({x:5, z: 4})"></button>
.o incluso con el reemplazo de la función:
<button ng-click="functionFromParent({function1: myfn, x:5, z: 4})"></button>
.es solo una expresión, no importa si es una función, o muchas funciones, o simplemente una comparación. Y puede reemplazar cualquier variable de esta expresión.
Ejemplos:
plantilla de directiva frente a código llamado:
padre ha definido $ scope.x, $ scope.y:
plantilla padre:
<myDirective expr="x==y"></myDirective>
<button ng-click="expr()"></button>
llamadas$scope.x==$scope.y
<button ng-click="expr({x: 5})"></button>
llamadas5 == $scope.y
<button ng-click="expr({x:5, y:6})"></button>
llamadas5 == 6
padre ha definido $ scope.function1, $ scope.x, $ scope.y:
plantilla padre:
<myDirective expr="function1(x) + y"></myDirective>
<button ng-click="expr()"></button>
Llamadas$scope.function1($scope.x) + $scope.y
<button ng-click="expr({x: 5})"></button>
Llamadas$scope.function1(5) + $scope.y
<button ng-click="expr({x:5, y:6})"></button>
llamadas$scope.function1(5) + 6
Directiva tiene como función $ scope.myFn:
<button ng-click="expr({function1: myFn, x:5, y:6})"></button>
llamadas$scope.myFn(5) + 6
fuente
Cuando usa {{title}}, solo el valor del alcance principal se pasará a la vista directiva y se evaluará. Esto se limita a un solo sentido, lo que significa que el cambio no se reflejará en el ámbito principal. Puede usar '=' cuando desee reflejar los cambios realizados en la directiva secundaria al ámbito primario también. Esto es de dos vías.
Cuando la directiva tiene un atributo de alcance (alcance: {}), ya no podrá acceder directamente al alcance principal. Pero aún así es posible acceder a él a través de scope. $ Parent, etc. Si elimina el alcance de la directiva, se puede acceder directamente.
Depende del contexto. Si desea llamar a una expresión o función con datos, use & y si desea compartir datos, puede usar la forma bidireccional usando '='
Puede encontrar las diferencias entre varias formas de pasar datos a la directiva en el siguiente enlace:
AngularJS - Ámbitos aislados - @ vs = vs &
http://www.codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs
fuente
@ Enlace de cadena de atributo (unidireccional) = Enlace de modelo bidireccional y enlace de método de devolución de llamada
fuente
@ vincula una propiedad de ámbito local / directiva al valor evaluado del atributo DOM. = vincula una propiedad de ámbito local / directiva a una propiedad de ámbito principal. & vinculante es para pasar un método al alcance de su directiva para que pueda llamarse dentro de su directiva.
@ Enlace de cadena de atributo = Enlace de modelo bidireccional y enlace de método de devolución de llamada
fuente