Tengo una directiva de formulario que usa un callback
atributo especificado con un alcance de aislamiento:
scope: { callback: '&' }
Se encuentra dentro de un, ng-repeat
por lo que la expresión que paso incluye el 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 termine con la directiva, llama $scope.callback()
desde su función de controlador. Para 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 dentro directive
.
¿Existe una expresión angular que permita esto: que $scope.callback(arg2)
resulte en callback
ser llamado con arguments = [item.id, arg2]
?
Si no, ¿cuál es la mejor manera 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 llamada directiva
$scope.callback.apply(null, [$scope.callbackArg].concat([arg2, arg3]) );
Pero no creo que sea particularmente bueno e implica poner cosas adicionales en el ámbito de aislamiento.
¿Hay una mejor manera?
Parque infantil Plunker aquí (tener la consola abierta).
fuente
ng
API, por ejemplo,ng-click="someFunction()"
es una expresión que evalúa la ejecución de una función.$scope.callback
lo establece elcallback="someFunction"
atributo y lascope: { callback: '=' }
propiedad del objeto de definición de directiva.$scope.callback
es una función que se llamará en una fecha posterior. El valor real del atributo es obviamente una cadena, que siempre es el caso con HTML.Respuestas:
Si declara su devolución de llamada como lo menciona @ lex82 como
Puede llamar al método de devolución de llamada en el ámbito de la directiva con el mapa de objetos y haría el enlace correctamente. Me gusta
sin requerir $ parse. Ver mi violín (registro de consola) http://jsfiddle.net/k7czc/2/
Actualización : hay un pequeño ejemplo de esto en la documentación :
fuente
No hay nada malo con las otras respuestas, pero uso la siguiente técnica cuando paso funciones en un atributo directivo.
Deja el paréntesis al incluir la directiva en tu html:
Luego "desenvuelva" la función en el enlace o controlador de su directiva. Aquí hay un ejemplo:
El paso "desenvolver" permite llamar la función utilizando una sintaxis más natural. También garantiza que la directiva funcione correctamente incluso cuando está anidada dentro de otras directivas que pueden pasar la función. Si no desenvolvió, entonces si tiene un escenario como este:
Entonces terminarías con algo como esto en tu directiva interna:
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.
fuente
this
puntero dentro del método de devolución de llamada, porque usa el alcance de la directiva. Estoy usando Typecript y mi devolución de llamada se ve así:public validateFirstName(firstName: string, fieldName: string): ng.IPromise<boolean> { var deferred = this.mQService.defer<boolean>(); ... .then(() => deferred.resolve(true)) .catch((msg) => { deferred.reject(false); }); return deferred.promise; }
En la directiva (
myDirective
):En plantilla directiva:
En fuente:
... donde
myFunction
se define en el controlador.Tenga
param
en cuenta que en la plantilla de directiva se enlaza perfectamenteparam
en la fuente y se establece enitem
.Para llamar desde dentro de la
link
propiedad de una directiva ("dentro" de ella), utilice un enfoque muy similar:fuente
Sí, hay una mejor manera: puede usar el servicio $ parse en su directiva para evaluar una expresión en el contexto del ámbito primario mientras vincula ciertos identificadores en la expresión a valores visibles solo dentro de su directiva:
Agregue esta línea a la función de enlace de la directiva donde puede acceder a los atributos de la directiva.
Su atributo de devolución de llamada se puede configurar como
callback = "callback(item.id, arg2)"
porque arg2 está vinculado a yourSecondArgument por el servicio $ parse dentro de la directiva. Directivas comong-click
permitirle acceder al evento click a través del$event
identificador dentro de la expresión pasada a la directiva usando exactamente este mecanismo.Tenga en cuenta que no tiene que hacer
callback
un miembro de su ámbito aislado con esta solución.fuente
scope.$parent
hace que la directiva "tenga fugas": "conoce" demasiado del mundo exterior, que un componente encapsulado bien diseñado no debería.Para mí lo siguiente funcionó:
en la directiva declararlo así:
En la plantilla directiva, úsela de la siguiente manera:
Y luego, cuando use la directiva, pase la función de esta manera:
Se pasa la función por su declaración y se llama desde la directiva y se completan los parámetros.
fuente