tipos personalizadas español directivas crear angular1 javascript angularjs angularjs-directive angularjs-scope

javascript - personalizadas - ¿Puede una directiva angular pasar argumentos a funciones en expresiones especificadas en los atributos de la directiva?



directive in angular español (4)

En directiva ( myDirective ):

... directive.scope = { boundFunction: ''&'', model: ''='', }; ... return directive;

En plantilla de directiva:

<div data-ng-repeat="item in model" data-ng-click=''boundFunction({param: item})''> {{item.myValue}} </div>

En fuente:

<my-directive model=''myData'' bound-function=''myFunction(param)''> </my-directive>

... donde myFunction está definido en el controlador.

Tenga en cuenta que param en la plantilla de directivas se une claramente a param en la fuente y se establece en el item .

Para llamar desde dentro de la propiedad de link de una directiva ("dentro" de ella), use un enfoque muy similar:

... directive.link = function(isolatedScope) { isolatedScope.boundFunction({param: "foo"}); }; ... return directive;

Tengo una directiva de formulario que usa un atributo de callback especificado con un alcance aislado:

scope: { callback: ''&'' }

Se encuentra dentro de una ng-repeat así que la expresión que paso incluye la id del objeto como un argumento para la función de devolución de llamada:

<directive ng-repeat = "item in stuff" callback = "callback(item.id)"/>

Cuando he terminado con la directiva, llama a $scope.callback() desde su función de controlador. En la mayoría de los casos, esto está bien, y es todo lo que quiero hacer, pero a veces me gustaría agregar otro argumento desde el interior de la directive .

¿Hay alguna expresión angular que permita esto: $scope.callback(arg2) , lo que hace que se llame a callback con arguments = [item.id, arg2] ?

Si no, ¿cuál es la mejor forma de hacer esto?

He descubierto que esto funciona:

<directive ng-repeat = "item in stuff" callback = "callback" callback-arg="item.id"/>

Con

scope { callback: ''='', callbackArg: ''='' }

y la vocación directiva

$scope.callback.apply(null, [$scope.callbackArg].concat([arg2, arg3]) );

Pero no creo que sea particularmente limpio e implica poner cosas adicionales en el alcance aislado.

¿Hay una mejor manera?

Parque infantil Plunker aquí (tener la consola abierta).


No hay nada malo con las otras respuestas, pero utilizo la siguiente técnica cuando paso funciones en un atributo directivo.

Deje el paréntesis cuando incluya la directiva en su html:

<my-directive callback="someFunction" />

Luego "desenvuelve" la función en el enlace o controlador de tu directiva. Aquí hay un ejemplo:

app.directive("myDirective", function() { return { restrict: "E", scope: { callback: "&" }, template: "<div ng-click=''callback(data)''></div>", // call function this way... link: function(scope, element, attrs) { // unwrap the function scope.callback = scope.callback(); scope.data = "data from somewhere"; element.bind("click",function() { scope.$apply(function() { callback(data); // ...or this way }); }); } } }]);

El paso "desenvolver" permite llamar a la función usando una sintaxis más natural. También asegura que la directiva funciona correctamente incluso cuando está anidada dentro de otras directivas que pueden pasar la función. Si no realizó el desenvolvimiento, entonces, si tiene un escenario como este:

<outer-directive callback="someFunction" > <middle-directive callback="callback" > <inner-directive callback="callback" /> </middle-directive> </outer-directive>

Entonces terminarías con algo como esto en tu directiva interna:

callback()()()(data);

Lo cual fallaría en otros escenarios de anidación.

Adapte esta técnica de un excelente artículo de Dan Wahlin en http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters

Agregué el paso de desenvolver para hacer que llamar a la función sea más natural y para resolver el problema de anidación que había encontrado en un proyecto.


Sí, hay una mejor manera: puede usar el servicio $ parse en su directiva para evaluar una expresión en el contexto del alcance principal, mientras vincula ciertos identificadores en la expresión a valores visibles solo dentro de su directiva:

$parse(attributes.callback)(scope.$parent, { arg2: yourSecondArgument });

Agregue esta línea a la función de enlace de la directiva donde puede acceder a los atributos de la directiva.

El atributo de devolución de llamada se puede establecer como callback = "callback(item.id, arg2)" porque arg2 está vinculado a yourSecondArgument por el servicio $ parse dentro de la directiva. Directivas como ng-click permiten acceder al evento click mediante el identificador $event dentro de la expresión pasada a la directiva utilizando exactamente este mecanismo.

Tenga en cuenta que no tiene que hacer que la callback un miembro de su alcance aislado con esta solución.


Si declara su devolución de llamada según lo mencionado por @ lex82

callback = "callback(item.id, arg2)"

Puede llamar al método de devolución de llamada en el ámbito de directivas con el mapa de objetos y lo haría correctamente. Me gusta

scope.callback({arg2:"some value"});

sin requerir $ parse. Ver mi violín (registro de la consola) http://jsfiddle.net/k7czc/2/

Actualización : hay un pequeño ejemplo de esto en la documentation :

& o & attr: proporciona una forma de ejecutar una expresión en el contexto del alcance principal. Si no se especifica ningún nombre de atributo, se supone que el nombre del atributo es el mismo que el nombre local. Dada la definición del alcance del widget: {localFn: ''& myAttr''}, la propiedad de ámbito aislado localFn apuntará a un contenedor de funciones para la expresión count = count + value. A menudo es conveniente pasar datos del ámbito aislado a través de una expresión y al alcance principal, esto se puede hacer pasando un mapa de nombres y valores de variables locales en el contenedor de expresiones fn. Por ejemplo, si la expresión es un incremento (cantidad), entonces podemos especificar el valor de la cantidad llamando a localFn como localFn ({amount: 22}).