Eu tenho um exemplo 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>
Eu quero que quando eu clicar no botão, a caixa de alerta aparecerá, mas nada aparecerá.
Alguém pode me ajudar?
Respostas:
222 para resposta № 1Para chamar uma função de controlador no escopo pai de dentro de uma diretiva de escopo isolado, use dash-separated
nomes de atributos no HTML como o OP disse.
Além disso, se você quiser enviar um parâmetro para sua função, chame a função passando um 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) {
}
}
});
139 para resposta № 2
Talvez eu esteja perdendo algo, mas embora as outras soluções chamem a função de escopo pai, não há capacidade de passar argumentos do código de diretiva, isso ocorre porque o update-fn
está chamando updateFn()
com parâmetros fixos, por exemplo {msg: "Hello World"}
. Uma ligeira alteração permite que a diretiva passe argumentos, o que eu considero muito mais útil.
<test color1="color1" update-fn="updateFn"></test>
Observe que o HTML está passando uma referência de função, ou seja, sem ()
colchetes.
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");
}
}
}
});
Então, acima, o HTML está chamando o escopo local callUpdate
, que então "busca" o updateFn do escopo pai e chama a função retornada com parâmetros que a diretiva pode gerar.
36 para resposta № 3
Na tag Html da diretiva "test", o nome do atributo da função não deveria ser camelCased, mas baseado em traços.
então - em vez de:
<test color1="color1" updateFn="updateFn()"></test>
Escreva:
<test color1="color1" update-fn="updateFn()"></test>
Esta é uma maneira angular de saber a diferença entre atributos de diretiva (como a função update-fn) e funções.
3 para resposta № 4
Que tal passar a função de controlador com ligação bidirecional? Em seguida, você pode usá-lo na diretiva exatamente da mesma maneira que em um modelo regular (retirei as partes irrelevantes para simplificar):
<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>
Aterrei nesta questão, porque tentei o método acima antes, mas de alguma forma não funcionou. Agora funciona perfeitamente.
2 para resposta № 5
use travessão e minúsculas para o nome do atributo (como outras respostas disseram):
<test color1="color1" update-fn="updateFn()"></test>
E use "=" em vez de "&" no escopo da diretiva:
scope: { updateFn: "="}
Em seguida, você pode usar updateFn como qualquer outra função:
<button ng-click="updateFn()">Click</button>
Ai está!
0 para a resposta № 6
Tive de usar a ligação "=" em vez de "&" porque não estava funcionando. Comportamento estranho.