angularjs: 无法通过独立指令范围内的“&”绑定将参数传递给父控制器方法
angularjs: can' t pass parameter to the parent controller method via '&' binding in isolated directive scope
在我的 angular 应用程序中,我定义了一个指令 foo-directive
,它被放置在父控制器中,如下所示:
<div ng-app="app">
<div ng-controller="ParentCtrl as parent">
<foo-directive data="parent.city" tab-click="parent.tClick()" tab-click2="parent.tClick2(v)"></foo-directive>
</div>
</div>
将两个方法:parent.tClick()
和 parent.tClick2(v)
传递到指令中并分别绑定到 tab-click
和 tab-click2
属性。不同的是第二个有个参数
JS代码如下:
function ParentCtrl($timeout){
this.city= "London";
this.tClick = function(){
console.log("debugging parent tclick...");
}
this.tClick2 = function(v){
console.log("debugging parent tclick2...");
console.log(v)
}
}
function FirstCtrl() {
this.$onInit = function(){
this.click = function(){
this.tabClick();
this.tabClick2("abc");
}
}
}
function fooDirective() {
return {
scope: {
data: '=',
tabClick : "&",
tabClick2: "&"
},
controller: 'FirstCtrl',
controllerAs: 'foo',
bindToController: true,
template: '<div ng-click="foo.click()">{{ foo.data }}</div>',
link: function ($scope, $element, $attrs, $ctrl) {
//console.log($ctrl.name);
}
};
}
现在问题来自第二种方法this.tabClick2("abc")
。有 TypeError
消息。我已经通过这个现场演示重现了这个问题:
https://jsfiddle.net/baoqger/sv4d03hk/1/
有什么帮助吗?
为您的 "FirstCtrl" 尝试以下代码片段:
function FirstCtrl() {
this.$onInit = function(){
this.click = function(){
this.tabClick({v: this.data});
}
}
}
当您使用表达式绑定 (&) 时,您需要使用包含 "v" 及其值的 JSON 显式调用它。像下面这样:
this.tabClick({v: this.data});
将函数传递给指令时,应将 "reference" 传递给函数,而不是函数的 "result"。加上括号,其实就是执行函数,返回结果给指令。由于函数 returns 都不是一个值,因此它们都将传递 undefined
.
鉴于您要传递给函数的参数值 (v
) 在指令范围内,而不是父级的范围内,您甚至不需要告诉指令函数接受一个参数。您只需将它传递给指令内的函数即可。即
<foo-directive data="parent.city" tab-click="parent.tClick" tab-click2="parent.tClick2"></foo-directive>
According to the docs,使用&
就是你要评估属性的结果:
The &
binding allows a directive to trigger evaluation of an expression in the context of the original scope, at a specific time.
相反,我们希望能够执行传递的属性,特别是给它一个变量。因此,=
(双向绑定)或 @
(单向绑定)可能更适合我们所追求的。
tabClick: "=",
tabClick2: "="
您也可以通过更新模板完全取消控制器。
template: '<div ng-click="foo.tabClick();foo.tabClick2(data)">{{ foo.data }}</div>'
function ParentCtrl($timeout) {
this.city = "London";
this.tClick = function() {
console.log("debugging parent tclick...");
}
}
function FirstCtrl() {}
function fooDirective() {
return {
scope: {
data: '=',
tabClick: "="
},
controller: 'FirstCtrl',
controllerAs: 'foo',
bindToController: true,
template: '<div ng-click="foo.tabClick(data)">{{ foo.data }}</div>',
link: function($scope, $element, $attrs, $ctrl) {
//console.log($ctrl.name);
}
};
}
angular
.module('app', [])
.directive('fooDirective', fooDirective)
.controller('FirstCtrl', FirstCtrl)
.controller('ParentCtrl', ParentCtrl)
<script src="https://code.angularjs.org/1.6.2/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="ParentCtrl as parent">
<foo-directive data="parent.city" tab-click=":: parent.tClick"></foo-directive>
</div>
</div>
PS。如果您担心使用 @
或 =
的性能,请考虑使用 ::
的一次性绑定。 IE。 <foo-directive data="parent.city" tab-click=":: parent.tClick" tab-click2=":: parent.tClick2"></foo-directive>
在我的 angular 应用程序中,我定义了一个指令 foo-directive
,它被放置在父控制器中,如下所示:
<div ng-app="app">
<div ng-controller="ParentCtrl as parent">
<foo-directive data="parent.city" tab-click="parent.tClick()" tab-click2="parent.tClick2(v)"></foo-directive>
</div>
</div>
将两个方法:parent.tClick()
和 parent.tClick2(v)
传递到指令中并分别绑定到 tab-click
和 tab-click2
属性。不同的是第二个有个参数
JS代码如下:
function ParentCtrl($timeout){
this.city= "London";
this.tClick = function(){
console.log("debugging parent tclick...");
}
this.tClick2 = function(v){
console.log("debugging parent tclick2...");
console.log(v)
}
}
function FirstCtrl() {
this.$onInit = function(){
this.click = function(){
this.tabClick();
this.tabClick2("abc");
}
}
}
function fooDirective() {
return {
scope: {
data: '=',
tabClick : "&",
tabClick2: "&"
},
controller: 'FirstCtrl',
controllerAs: 'foo',
bindToController: true,
template: '<div ng-click="foo.click()">{{ foo.data }}</div>',
link: function ($scope, $element, $attrs, $ctrl) {
//console.log($ctrl.name);
}
};
}
现在问题来自第二种方法this.tabClick2("abc")
。有 TypeError
消息。我已经通过这个现场演示重现了这个问题:
https://jsfiddle.net/baoqger/sv4d03hk/1/
有什么帮助吗?
为您的 "FirstCtrl" 尝试以下代码片段:
function FirstCtrl() {
this.$onInit = function(){
this.click = function(){
this.tabClick({v: this.data});
}
}
}
当您使用表达式绑定 (&) 时,您需要使用包含 "v" 及其值的 JSON 显式调用它。像下面这样:
this.tabClick({v: this.data});
将函数传递给指令时,应将 "reference" 传递给函数,而不是函数的 "result"。加上括号,其实就是执行函数,返回结果给指令。由于函数 returns 都不是一个值,因此它们都将传递 undefined
.
鉴于您要传递给函数的参数值 (v
) 在指令范围内,而不是父级的范围内,您甚至不需要告诉指令函数接受一个参数。您只需将它传递给指令内的函数即可。即
<foo-directive data="parent.city" tab-click="parent.tClick" tab-click2="parent.tClick2"></foo-directive>
According to the docs,使用&
就是你要评估属性的结果:
The
&
binding allows a directive to trigger evaluation of an expression in the context of the original scope, at a specific time.
相反,我们希望能够执行传递的属性,特别是给它一个变量。因此,=
(双向绑定)或 @
(单向绑定)可能更适合我们所追求的。
tabClick: "=",
tabClick2: "="
您也可以通过更新模板完全取消控制器。
template: '<div ng-click="foo.tabClick();foo.tabClick2(data)">{{ foo.data }}</div>'
function ParentCtrl($timeout) {
this.city = "London";
this.tClick = function() {
console.log("debugging parent tclick...");
}
}
function FirstCtrl() {}
function fooDirective() {
return {
scope: {
data: '=',
tabClick: "="
},
controller: 'FirstCtrl',
controllerAs: 'foo',
bindToController: true,
template: '<div ng-click="foo.tabClick(data)">{{ foo.data }}</div>',
link: function($scope, $element, $attrs, $ctrl) {
//console.log($ctrl.name);
}
};
}
angular
.module('app', [])
.directive('fooDirective', fooDirective)
.controller('FirstCtrl', FirstCtrl)
.controller('ParentCtrl', ParentCtrl)
<script src="https://code.angularjs.org/1.6.2/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="ParentCtrl as parent">
<foo-directive data="parent.city" tab-click=":: parent.tClick"></foo-directive>
</div>
</div>
PS。如果您担心使用 @
或 =
的性能,请考虑使用 ::
的一次性绑定。 IE。 <foo-directive data="parent.city" tab-click=":: parent.tClick" tab-click2=":: parent.tClick2"></foo-directive>