switch - AngularJS: ¿Diferencias entre=y @ en el alcance de la directiva?
ng-href angularjs (2)
Resumen
- @attr se une a un valor de cadena evaluado del atributo DOM coincidente.
- = attr se une a una propiedad de alcance del atributo DOM correspondiente.
- & attr se une a una función de alcance del atributo DOM correspondiente.
- @
- =
- &
Usamos el 4, 5 y 6 si el nombre del atributo DOM del objetivo coincide con el nombre de propiedad del alcance aislado. Aquí hay un fiddle funcional del siguiente ejemplo.
Html
<div ng-app=''isolate''>
<h3>Outer Scope</h3>
<input type="text" ng-model="myModel" />
<p>msg: {{ msg }}</p>
<h3>Inner Scope</h3>
<div id="inner">
<div my-directive at="{{ myModel }}" equals="myModel" ampersand="msg=msg+''click''"></div>
</div>
</div>
Javascript
angular.module(''isolate'', [])
.directive(''myDirective'', function () {
return {
template:
''<label>@attr</label><input value="{{ myAt }}" />'' +
''<label>@</label><input value="{{ at }}" />'' +
''<label>=attr</label><input ng-model="myEquals" />'' +
''<label>=</label><input ng-model="equals" />'' +
''<label>&attr</label><input type="button" ng-click="myAmpersand()" value="Btn" />'' +
''<label>&</label><input type="button" ng-click="ampersand()" value="Btn" />'',
scope: {
myAt: ''@at'',
myEquals: ''=equals'',
myAmpersand: ''&ersand'',
at: ''@'',
equals: ''='',
ampersand: ''&''
}
};
});
Esta pregunta ya tiene una respuesta aquí:
La creación de un alcance aislado dentro de una directiva nos permite asignar el alcance externo al ámbito interno . Hemos visto seis formas diferentes de asignar a attrbutes:
- = attr
- & attr
- @attr
- =
- &
- @
¿Qué hacen cada una de estas opciones de mapeo de alcance?
Esto puede ser confuso pero espero que un simple ejemplo lo aclare. Primero, separando los enlaces de modelos de los comportamientos.
Aquí hay un violín que debería ayudar a unir las cosas: http://jsfiddle.net/jeremylikness/3pvte/
Y explicó ... si su directiva se ve así:
<my-directive target="foo"/>
Entonces tienes estas posibilidades para el alcance:
{ target : ''='' }
Esto vinculará scope.target (directiva) a $ scope.foo (ámbito externo). Esto se debe a que = es para vinculación bidireccional y cuando no especifica nada, automáticamente coincide con el nombre en el ámbito interno con el nombre del atributo en la directiva. Los cambios en scope.target actualizarán $ scope.foo.
{ bar : ''=target'' }
Esto vinculará scope.bar a $ scope.foo. Esto se debe a que, una vez más, especificamos el enlace bidireccional, pero le indicamos a la directiva que lo que está en el atributo "objetivo" debe aparecer en el ámbito interno como "barra". Los cambios en scope.bar actualizarán $ scope.foo.
{ target : ''@'' }
Esto establecerá scope.target en "foo" porque @ significa "tómalo literalmente". Los cambios en scope.target no se propagarán fuera de su directiva.
{ bar : ''@target'' }
Esto establecerá scope.bar en "foo" porque @ toma su valor del atributo de destino. Los cambios en scope.bar no se propagarán fuera de su directiva.
Ahora hablemos de comportamientos. Supongamos que su alcance externo tiene esto:
$scope.foo = function(parm1, parm2) { console.log(parm1 + ": " + parm2); }
Hay varias formas de acceder a esto. Si tu HTML es:
<my-directive target=''foo''>
Entonces
{ target : ''='' }
Te permitirá llamar a scope.target (1,2) desde tu directiva.
La misma cosa,
{ bar : ''=target'' }
Le permite llamar a scope.bar (1,2) desde su directiva.
La forma más común es establecer esto como un comportamiento. Técnicamente, ampersand evalúa una expresión en el contexto del padre. Eso es importante. Entonces podría tener:
<my-directive target="a+b" />
Y si el alcance principal tiene $ scope.a = 1 y $ scope.b = 2, entonces en mi directiva:
{ target: ''&'' }
Puedo llamar a scope.target () y el resultado será 3. Esto es importante: el enlace se expone como una función del ámbito interno, pero la directiva puede vincularse a una expresión.
Una forma más común de hacer esto es:
<my-directive target="foo(val1,val2)">
Entonces puedes usar:
{ target: ''&'' }
Y llamada de la directiva:
scope.target({val1: 1, val2: 2});
Esto toma el objeto que pasó, asigna las propiedades a los parámetros en la expresión evaluada y luego llama al comportamiento, en este caso se llama a $ scope.foo (1,2);
También puedes hacer esto:
<my-directive target="foo(1, val)"/>
Esto bloquea el primer parámetro del literal 1 y de la directiva:
{ bar: ''&target'' }
Entonces:
scope.bar(5)
Lo que llamaría $ scope.foo (1,5);