Javascript Angular JS:指令&x2019;当我们已经有指令’;有范围的控制器?
我需要对范围和模板执行一些操作。似乎我可以在Javascript Angular JS:指令&x2019;当我们已经有指令’;有范围的控制器?,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我需要对范围和模板执行一些操作。似乎我可以在链接功能或控制器功能中这样做(因为两者都可以访问范围) 什么时候我必须使用链接功能而不是控制器 angular.module('myApp').directive('abc', function($timeout) { return { restrict: 'EA', replace: true, transclude: true, scope: true, lin
链接
功能或控制器
功能中这样做(因为两者都可以访问范围)
什么时候我必须使用链接
功能而不是控制器
angular.module('myApp').directive('abc', function($timeout) {
return {
restrict: 'EA',
replace: true,
transclude: true,
scope: true,
link: function(scope, elem, attr) { /* link function */ },
controller: function($scope, $element) { /* controller function */ }
};
}
另外,我知道link
是一个无角度的世界。因此,我可以使用$watch
,$digest
和$apply
当我们已经有控制器时,链接
功能的意义是什么?为什么需要控制器
angular.module('myApp').directive('abc', function($timeout) {
return {
restrict: 'EA',
replace: true,
transclude: true,
scope: true,
link: function(scope, elem, attr) { /* link function */ },
controller: function($scope, $element) { /* controller function */ }
};
}
当您希望在DOM中嵌套指令并将父指令中的API函数公开给嵌套指令时,link
和controller
之间的区别就开始发挥作用
从:
最佳实践:当您想向其他指令公开API时,请使用controller。否则请使用链接
假设您希望有两个指令我的表单
和我的文本输入
,并且您希望我的文本输入
指令只出现在我的表单
中,而不出现在其他任何地方
在这种情况下,在定义指令my text input
时,您会说它需要一个来自parent
DOM元素的控制器,使用require参数,如下所示:require:'^myForm'
。现在,父元素的控制器将作为第四个参数$scope,element,attributes
之后的注入链接
函数中。您可以在该控制器上调用函数并与父指令通信
此外,如果找不到这样的控制器,则会引发错误
为什么要使用链接
如果正在定义控制器
,则实际上不需要使用链接
功能,因为控制器
上有$scope
。此外,在定义链接
和控制器
时,确实需要注意两者的调用顺序(控制器
之前执行)
然而,与角度方式一致,大多数使用$watchers
的DOM操作和双向绑定通常在链接
函数中完成,而用于子对象和$scope
操作的API则在控制器
中完成。这不是一条硬性规定,但这样做将使代码更加模块化,并有助于分离关注点(控制器将保持指令
状态,链接
函数将保持DOM
+外部绑定).控制器
函数/对象表示抽象模型-视图-控制器(MVC)。虽然MVC并没有什么新鲜的东西可写,但它仍然是angular最显著的优势:将关注点分割成更小的部分。仅此而已,如果您需要对来自视图的模型更改做出反应,控制器就是做这项工作的合适人选
关于link
函数的故事是不同的,它来自不同的视角,然后是MVC。一旦我们想要跨越控制器/模型/视图
(模板)的边界,这是非常重要的
让我们从传递到链接中的参数开始:
function link(scope, element, attrs) {
- 范围是一个角度范围对象
- 元素是此指令匹配的jqLite包装元素
- attrs是一个具有规范化属性名称及其对应值的对象
要将链接
放到上下文中,我们应该提到所有指令都要经过这个初始化过程步骤:编译、链接。摘自Brad Green和Shyam Seshadri的书:
编译阶段(link的姐妹,让我们在这里提及它以获得清晰的图片):
在此阶段,Angular遍历DOM以识别所有已注册的
模板中的指令。对于每个指令,它将转换
基于指令规则的DOM(模板、替换、转包和
依此类推),并调用编译函数(如果存在)。结果是一场灾难
编译模板函数
链接阶段:
要使视图成为动态视图,请为每个视图运行链接函数
指令。链接函数通常在DOM上创建侦听器
或者模型。这些侦听器使视图和模型保持同步
一直都是
在这里可以找到如何使用链接的一个很好的示例:。请参见示例:创建一个指令来操作DOM,该指令在页面中插入一个“日期-时间”,每秒钟刷新一次
只是上面rich源代码中的一个很短的片段,展示了DOM的真正操作。有一个钩住$timeout服务的函数,它在析构函数调用中被清除,以避免内存泄漏
.directive('myCurrentTime', function($timeout, dateFilter) {
function link(scope, element, attrs) {
...
// the not MVC job must be done
function updateTime() {
element.text(dateFilter(new Date(), format)); // here we are manipulating the DOM
}
function scheduleUpdate() {
// save the timeoutId for canceling
timeoutId = $timeout(function() {
updateTime(); // update DOM
scheduleUpdate(); // schedule the next update
}, 1000);
}
element.on('$destroy', function() {
$timeout.cancel(timeoutId);
});
...
在我的初始与链接
和控制器
函数斗争并阅读了大量有关它们的内容后,我想现在我找到了答案
首先让理解
简而言之,角度指令是如何工作的:
- 我们从模板开始(作为字符串或加载到字符串)
var templateString='{{5+10}}'代码>
- 现在,这个
templateString
被包装成一个角度元素
var el=angular.element(templateString)代码>
- 使用
el
,现在我们使用$compile
编译它,以返回链接函数
var l=$compile(el)
下面是发生的情况
$compile