AngularJS指令与控制器耦合时不能传入不同的函数
AngularJS can't pass in different function when directive coupled with controller
我有一个指令,我想将其作为一个组件与控制器紧密耦合。我假设我通过显式传递我的函数来遵循最佳实践,即使我声明要使用控制器也是如此。这是一个例子:
app.js
var app = angular.module('plunker', [])
app
.controller('myCtrl', function($scope) {
$scope.output = '';
$scope.foo = function () {
$scope.output = 'foo';
}
$scope.bar = function () {
$scope.output = 'bar';
}
})
.directive('myDirective', function() {
return {
scope: {
output: '=',
foo: '&',
},
templateUrl: 'template.html',
replace: true,
controller: 'myCtrl',
};
})
template.html
<div>
<button ng-click="foo()">Click Foo</button>
<p>You clicked: <span style="color:red">{{output}}</span></p>
</div>
index.html
<body>
<my-directive
output="output"
foo="bar()"> <!-- pass in the *bar* function instead of the *foo* function -->
</my-directive>
</body>
Plunkr:http://plnkr.co/edit/Y4lhxuXbK9YbjAklR7v1?p=preview
在这里,即使我传入了 bar()
函数,但在单击按钮时输出为 'foo'。如果我通过在指令中注释掉 controller: 'myCtrl'
来解耦控制器,输出将变为 'bar'.
我想我可以声明控制器,但仍然可以自由地将我想要的函数传递给指令。如果指令只是查找控制器以找到它,那么显式传递这些函数似乎也有点多余(我可以不传递任何东西到指令中,它仍然有效)。
这在测试时尤其有问题,因为我想将自己的存根函数传递给指令,但目前我无法做到。
有什么方法可以实现我想要的,还是我做错了什么?
EDIT 我的意思是不在 HTML.
中声明控制器
当 运行 在指令中时,$scope 在调用控制器构造函数之前用输出和 foo 变量初始化。您的控制器实际上正在覆盖这些属性。
在您的控制器中进行简单检查
if(!$scope.foo)
{
$scope.foo = function () {
$scope.output = 'foo';
}
}
会起作用。
PS。我假设你的例子是你问题的简化。如果不是,那么其他答案的建议就是简单地从指令中删除控制器是最好的方法。
删除指令上的 controller
属性:
.directive('myDirective', function() {
return {
scope: {
output: '=',
foo: '&',
},
templateUrl: 'template.html',
replace: true,
// controller: 'myCtrl',
};
})
您正在将同一个控制器连接到指令作为父指令,这将覆盖您试图通过隔离范围传入的所有属性。控制器连接 两次 ,一次在父作用域上,然后在指令上再次连接。去掉这个可以让你传入函数bar()
,不会被覆盖
我有一个指令,我想将其作为一个组件与控制器紧密耦合。我假设我通过显式传递我的函数来遵循最佳实践,即使我声明要使用控制器也是如此。这是一个例子:
app.js
var app = angular.module('plunker', [])
app
.controller('myCtrl', function($scope) {
$scope.output = '';
$scope.foo = function () {
$scope.output = 'foo';
}
$scope.bar = function () {
$scope.output = 'bar';
}
})
.directive('myDirective', function() {
return {
scope: {
output: '=',
foo: '&',
},
templateUrl: 'template.html',
replace: true,
controller: 'myCtrl',
};
})
template.html
<div>
<button ng-click="foo()">Click Foo</button>
<p>You clicked: <span style="color:red">{{output}}</span></p>
</div>
index.html
<body>
<my-directive
output="output"
foo="bar()"> <!-- pass in the *bar* function instead of the *foo* function -->
</my-directive>
</body>
Plunkr:http://plnkr.co/edit/Y4lhxuXbK9YbjAklR7v1?p=preview
在这里,即使我传入了 bar()
函数,但在单击按钮时输出为 'foo'。如果我通过在指令中注释掉 controller: 'myCtrl'
来解耦控制器,输出将变为 'bar'.
我想我可以声明控制器,但仍然可以自由地将我想要的函数传递给指令。如果指令只是查找控制器以找到它,那么显式传递这些函数似乎也有点多余(我可以不传递任何东西到指令中,它仍然有效)。
这在测试时尤其有问题,因为我想将自己的存根函数传递给指令,但目前我无法做到。
有什么方法可以实现我想要的,还是我做错了什么?
EDIT 我的意思是不在 HTML.
中声明控制器当 运行 在指令中时,$scope 在调用控制器构造函数之前用输出和 foo 变量初始化。您的控制器实际上正在覆盖这些属性。
在您的控制器中进行简单检查
if(!$scope.foo)
{
$scope.foo = function () {
$scope.output = 'foo';
}
}
会起作用。
PS。我假设你的例子是你问题的简化。如果不是,那么其他答案的建议就是简单地从指令中删除控制器是最好的方法。
删除指令上的 controller
属性:
.directive('myDirective', function() {
return {
scope: {
output: '=',
foo: '&',
},
templateUrl: 'template.html',
replace: true,
// controller: 'myCtrl',
};
})
您正在将同一个控制器连接到指令作为父指令,这将覆盖您试图通过隔离范围传入的所有属性。控制器连接 两次 ,一次在父作用域上,然后在指令上再次连接。去掉这个可以让你传入函数bar()
,不会被覆盖