我正在尝试编写组件式AngularJS,类似于此article提出的做法。
但是,我已经意识到有各种方法可以将函数传递给相关控制器的指令。我正在处理的指令非常复杂,我通过绑定到模板中的指令传递每个函数,但我现在看到我可以隐式继承$scope
对象或引用Controller
直接反对。
这是我的意思的一个例子:
app.js
var app = angular.module('plunker', [])
app
.controller('myCtrl', function($scope) {
$scope.output = '';
// fn foo is passed into directive as an argument
$scope.foo = function () {
$scope.output = 'foo';
}
// fn inherited from controller
$scope.bar = function () {
$scope.output = 'bar';
}
// fn attached to ctrl object and referenced directly
this.baz = function () {
$scope.output = 'baz';
}
})
.directive('myDirective', function() {
return {
scope: {
output: '=',
foo: '&',
},
templateUrl: 'template.html',
replace: true,
controller: 'myCtrl',
controllerAs: 'ctrl'
};
})
的index.html
<body ng-controller="myCtrl">
<my-directive
output="output"
foo="foo()">
</my-directive>
</body>
template.html
<div>
<button ng-click="foo()">Click Foo</button>
<button ng-click="bar()">Click Bar</button>
<button ng-click="ctrl.baz()">Click Baz</button>
<p>You clicked: <span style="color:red">{{output}}</span></p>
</div>
Plunkr:http://plnkr.co/edit/1JzakaxL3D2L6wpPXz3v?p=preview
所以这里有三个函数,它们都可以工作,但是以不同的方式传递给指令。我的问题是,从代码和可测试性的角度来看,每个优点是什么,哪个是最好的?
答案 0 :(得分:1)
您并没有真正向指令传递任何内容,因为它使用相同的控制器作为包含它的文件...
例如,如果删除以下内容:
scope: {
output: '=',
foo: '&',
}
从你的指令,一切仍然有效。我无法想到为指令使用相同的控制器以及包含这样的应用程序的原因。我永远不会推荐这种方法。
如果你也删除
controller: 'myCtrl',
controllerAs: 'ctrl'
仅foo
和bar
有效。这是因为该指令继承了它所包含的范围。仅当你的指令非常简单并且使用它与视图紧密耦合时,才建议这样做。通常这种方法可以在您进行一些在页面中重复的视觉修改时使用。请注意,当您在控制器中更改某些内容时,该指令可能会中断,这违反了封装原则。
最后,将函数传递给指令的正确方法确实是使用'&'
修饰符。这使得您的指令保持一个独立的范围,这意味着如果包含控制器上的某些代码发生更改,它将不会中断。这使您的指令真正成为一个封装的独立模块,您可以拖放&#34;任何地方。