/ / AngularJS - pasar función a directiva - angularjs

AngularJS - pasar la función a la directiva - angularjs

Tengo un ejemplo angularJS

<div ng-controller="testCtrl">

<test color1="color1" updateFn="updateFn()"></test>
</div>
<script>
angular.module("dr", [])
.controller("testCtrl", function($scope) {
$scope.color1 = "color";
$scope.updateFn = function() {
alert("123");
}
})
.directive("test", function() {
return {
restrict: "E",
scope: {color1: "=",
updateFn: "&"},
template: "<button ng-click="updateFn()">Click</button>",
replace: true,
link: function(scope, elm, attrs) {
}
}
});

</script>
</body>

</html>

Cuando haga clic en el botón Quiero, aparecerá el cuadro de alerta, pero no se mostrará nada.

¿Alguien puede ayudarme?

Respuestas

222 para la respuesta № 1

Para llamar a una función de controlador en el ámbito primario desde dentro de una directiva de ámbito aislado, use dash-separated nombres de atributos en el HTML como dijo el OP.

Además, si desea enviar un parámetro a su función, llame a la función pasando un objeto:

<test color1="color1" update-fn="updateFn(msg)"></test>

JS

var app = angular.module("dr", []);

app.controller("testCtrl", function($scope) {
$scope.color1 = "color";
$scope.updateFn = function(msg) {
alert(msg);
}
});

app.directive("test", function() {
return {
restrict: "E",
scope: {
color1: "=",
updateFn: "&"
},
// object is passed while making the call
template: "<button ng-click="updateFn({msg : "Hello World!"})">
Click</button>",
replace: true,
link: function(scope, elm, attrs) {
}
}
});

Violín


139 para la respuesta № 2

Quizás me estoy perdiendo algo, pero aunque las otras soluciones sí llaman a la función de alcance principal, no hay capacidad para pasar argumentos del código de la directiva, esto se debe a que update-fn esta llamando updateFn() con parámetros fijos, por ejemplo en {msg: "Hello World"}. Un ligero cambio permite que la directiva pase argumentos, lo que creo que es mucho más útil.

<test color1="color1" update-fn="updateFn"></test>

Tenga en cuenta que el HTML está pasando una referencia de función, es decir, sin () soportes.

JS

var app = angular.module("dr", []);

app.controller("testCtrl", function($scope) {
$scope.color1 = "color";
$scope.updateFn = function(msg) {
alert(msg);
}
});

app.directive("test", function() {
return {
restrict: "E",
scope: {
color1: "=",
updateFn: "&"
},
// object is passed while making the call
template: "<button ng-click="callUpdate()">
Click</button>",
replace: true,
link: function(scope, elm, attrs) {
scope.callUpdate = function() {
scope.updateFn()("Directive Args");
}
}
}
});

Entonces, en lo anterior, el HTML está llamando al alcance local callUpdate función, que luego "obtiene" el updateFn del ámbito primario y llama a la función devuelta con los parámetros que la directiva puede generar.

http://jsfiddle.net/mygknek2/


36 para la respuesta № 3

En su etiqueta Html de la directiva "prueba", el nombre del atributo de la función no debería ser camelCased, pero basado en el tablero.

entonces, en lugar de:

<test color1="color1" updateFn="updateFn()"></test>

escribir:

<test color1="color1" update-fn="updateFn()"></test>

Esta es la forma angular de distinguir entre los atributos de la directiva (como la función update-fn) y las funciones.


3 para la respuesta № 4

¿Qué tal pasar la función del controlador con enlace bidireccional? Luego puede usarlo en la directiva exactamente de la misma manera que en una plantilla normal (eliminé las partes irrelevantes por simplicidad):

<div ng-controller="testCtrl">

<!-- pass the function with no arguments -->
<test color1="color1" update-fn="updateFn"></test>
</div>

<script>
angular.module("dr", [])
.controller("testCtrl", function($scope) {
$scope.updateFn = function(msg) {
alert(msg);
}
})
.directive("test", function() {
return {
scope: {
updateFn: "=" // "=" bidirectional binding
},
template: "<button ng-click="updateFn(1337)">Click</button>"
}
});
</script>

Aterricé en esta pregunta, porque probé el método anterior, pero de alguna manera no funcionó. Ahora funciona perfectamente.


2 para la respuesta № 5

use guiones y minúsculas para el nombre del atributo (como dicen otras respuestas):

 <test color1="color1" update-fn="updateFn()"></test>

Y use "=" en lugar de "&" en el alcance de la directiva:

 scope: { updateFn: "="}

Luego puede usar updateFn como cualquier otra función:

 <button ng-click="updateFn()">Click</button>

¡Ahí tienes!


0 para la respuesta № 6

Tuve que usar el enlace "=" en lugar de "&" porque eso no funcionaba. Comportamiento extraño.