我听说将controllerAs语法和bindToController: true使用隔离范围的in指令一起使用是一种好习惯。参考文献:一,二
controllerAs
bindToController: true
假设我有一个这样的指令:
angular.module('MyModule').directive('MyDirective', function(User) { return { scope: { name: '=' }, templateUrl: 'my-template.html', link: function(scope) { scope.User = User; scope.doSomething = function() { // Do something cool }; } }; }); <!-- my-template.html --> <div> User Id: {{ User.id }} Name: {{ name }} <button ng-click="doSomething()">Do it</button> </div>
如您所见,该指令中没有控制器。但是,为了能够发挥作用controllerAs,bindToController: true我必须拥有一个控制器。
将链接功能转换为控制器的最佳实践是吗?
angular.module('MyModule').directive('MyDirective', function(User) { return { scope: { name: '=' }, templateUrl: 'my-template.html', bindToController: true, controllerAs: 'myCtrl', controller: function() { this.User = User; this.doSomething = function() { // Do something cool }; } }; }); <!-- my-template.html --> <div> User Id: {{ myCtrl.User.id }} Name: {{ myCtrl.name }} <button ng-click="myCtrl.doSomething()">Do it</button> </div>
我的理解是,指令的控制器应该用作公开指令与指令通信的指令API的机制。
考虑到Angular 2.0,有人能阐明这些天的最佳做法吗?
我认为最好的做法是在指令的控制器内移动初始化代码和/或公开API函数,因为这样做有两个目的:
1. Intialization of $scope 2. Exposing an API for communication between directives
假设您的指令定义了子作用域(或继承作用域)。如果在链接函数内部初始化作用域,则子作用域将无法通过作用域继承访问此处定义的任何作用域变量。这是因为父链接功能总是在子链接功能之后执行。因此,范围初始化的适当位置在控制器功能内部。
子指令可以通过指令定义对象上的’require’属性访问父指令的控制器。这允许指令进行通信。为了使它起作用,必须完全定义父控制器,以便可以从子指令的链接功能对其进行访问。实现此目的的最佳位置是控制器功能本身的定义。父控制器功能始终在子控制器功能之前被调用。
重要的是要了解链接功能和控制器功能有两个截然不同的目的。控制器功能设计用于初始化和指令通信,链接器功能设计用于运行时行为。根据代码的意图,您应该能够确定它是属于控制器还是属于链接器。
您是否应该将任何用于初始化作用域的代码从链接功能移至控制器功能?
是的,这是控制器功能存在的主要原因之一:初始化作用域,并允许其作用域参与原型作用域继承。
您是否应该将$ watch处理程序从链接功能移动到控制器功能?
否。链接功能的目的是连接行为并可能操纵DOM。在链接功能中,所有指令均已编译,并且所有子链接功能均已执行。这使它成为连接行为的理想场所,因为它已尽可能接近DOM准备就绪(直到在Render阶段之后才真正为DOM准备就绪)。