我知道$scope
中的controller
可以与directives
中的链接功能共享。
例如,在这段代码中,我可以从声明的控制器调用一个函数,在浏览器控制台上打印“Hello World”:
.directive('myDirective', [function () {
return {
restrict : 'E',
replace : true,
controller: 'MyController',
templateUrl : 'directives/myDirective.tpl.html',
link : function (scope, elem, attrs, controller) {
scope.message = 'Hello World!';
}
};
}])
.controller('MyController', [function ($scope, $element, $attrs, $log, $timeout) {
// $timeout to wait the link function to be ready.
$timeout(function () {
// This prints Hello World as expected.
$log.debug($scope.message);
});
});
}])
好的,这很好用。
我的问题是:
DOM
中的controller
元素,仅在link function
中操作。controller
中操纵DOM元素吗?即使$scope
,$elem
等相同?这些是我在Angular Directive documentation上找不到的问题。
答案 0 :(得分:14)
在这种方法中,控制器和指令之间共享的SAME范围是什么?
是的,是的。
使用这种方法会产生什么后果?我们假设我不会在控制器中操纵DOM元素,只能在链接函数中操作。
控制器提供指令的行为,就像常规的Angular应用程序一样。也就是说,你应该只操纵控制器功能内的范围。如果需要从链接函数更改范围,请调用它的方法。此外,由于控制器是在链接功能之前执行的,因此您应该在前者中初始化范围,以便后者可以获得有效的模型。
我真的需要避免在这个控制器中操纵DOM元素吗?即使$ scope,$ elem等都相同?
根据定义,链接函数是执行DOM操作的地方。我找不到一个技术原因会阻止你操纵指令控制器中的DOM,除非你不应该。实际上,为了检查我刚刚更改了一个我已编写的指令并将所有代码从链接函数移动到控制器函数,所有内容都保持有效。但如果你将范围逻辑和DOM操作混合在一起,我认为很难找出正在发生的事情。
最后,您可能会发现这篇文章很有用:Understanding Directives。
答案 1 :(得分:5)
1)是的,它们都共享相同的范围,因为你使用指令的控制器来记录范围,这意味着你可以将'MyController'放在指令中,就像这样
return {
replace: true,
controller: function($scope,...){ // equals MyController
}
}
如果控制器是指令的包装而不是指令,并且指令范围设置为true或对象哈希,那么它们将不会共享相同的范围。
2)没有后果,只是不要操纵控制器中的DOM,控制器的一个用途是将指令连接在一起以从服务或通过简单的扩充获取或设置数据范围(即:scope.message =“Hello World”)无论哪种方式都需要最小化。如果你想在其他指令之间共享数据,你只需要这个指令的控制器,那么你设置它的方式是理想的。
3)是的,避免控制器中的DOM操作,其不意味着表示逻辑或用户看到的内容,即指令的作用,记住SOC(关注点分离)的每个部分MVC / MV *模式有自己的发挥。
以一种简单的方式来思考它,就像这个用户看到表示层上的按钮,用户单击按钮一个功能,点击按钮就会出现在业务层(控制器)上,它将结果存储在数据/模型层中。
警告如果按钮执行除了处理用户和数据层之间的命令(计算,评估等)以外的任何操作,例如添加函数属于指令内的类(DOM操作)。 / p>
精彩的阅读和更深入的here
答案 2 :(得分:1)
请参阅更新的plunker:http://plnkr.co/edit/pT8rEDz7gWKUPYIZhUYA?p=preview
Angular的一个优点是指令,所以我会尽可能地使用它们来区分你的顾虑。