Yug*_*dle 193 javascript angularjs angularjs-directive
我需要对范围和模板执行一些操作.似乎我可以在link函数或controller函数中执行此操作(因为它们都可以访问范围).
什么时候我必须使用link功能而不是控制器?
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 */ }
};
}
Run Code Online (Sandbox Code Playgroud)
另外,我明白这link是非角度的世界.所以,我可以使用$watch,$digest和$apply.
link当我们已经拥有控制器时,该功能有什么意义?
Yug*_*dle 293
我经过最初的一起奋斗link和controller功能,阅读了很多关于他们的,我想现在我找到了答案.
首先让我们理解,
角度指令如何工作简而言之:
我们从模板开始(作为字符串或加载到字符串)
var templateString = '<div my-directive>{{5 + 10}}</div>';
现在,它templateString被包裹为角元素
var el = angular.element(templateString);
有了el,现在我们编译它$compile以取回链接功能.
var l = $compile(el)
这是发生了什么,
$compile 遍历整个模板并收集它识别的所有指令.link会收集它们的函数.link函数都包装在一个新link函数中并返回为l.最后,我们为scope这个l(链接)函数提供函数,该函数进一步用它scope及其相应的元素执行包装的链接函数.
l(scope)
这会将template作为新节点添加到DOM并调用controller,这会将其监视添加到与DOM中的模板共享的范围.

比较编译与链接与控制器:
每个指令只编译一次,并保留链接功能以便重复使用.因此,如果某个指令的所有实例都适用,则应在指令compile函数内执行.
现在,在编译之后,我们将link函数在将模板附加到DOM时执行.因此,我们执行特定于指令的每个实例的所有内容.例如:附加事件,根据范围改变模板等.
最后,当指令在(在连接之后)工作时,控制器可用于实时和被动DOM.因此:
(1 )用链接设置视图[ V ](即模板)后.$scope是我们的[ M ]并且$controller是我们在MVC中的 [ C ]
(2)通过设置手表,利用$ scope 的双向绑定.
(3)$scope预计手表会被添加到控制器中,因为这是在运行期间观看模板的内容.
(4)最后,controller也用于能够在相关指令之间进行通信.(myTabs例如https://docs.angularjs.org/guide/directive中的示例)
(5)确实,我们可以在link功能中完成所有这些,但关于关注点的分离.
因此,最后我们有以下完美契合所有部分:

mus*_*_ut 74
之间的差异link和controller当你想在你的DOM巢指令和从父指令嵌套那些暴露的API函数的用武之地.
来自文档:
最佳实践:当您希望将API公开给其他指令时,请使用控制器.否则使用链接.
假设您希望有两个指令my-form,my-text-input并且您希望my-text-input指令仅在内部my-form和其他地方出现.
在这种情况下,您将在定义指令时my-text-input说它需要parent使用require参数从DOM元素中获取控制器,如下所示:require: '^myForm'.现在来自父元素的控制器将作为第四个参数injected进入link函数,如下所示$scope, element, attributes.您可以在该控制器上调用函数并与父指令通信.
此外,如果找不到这样的控制器,则会引发错误.
没有真正需要使用该link函数,如果一个人正在定义,controller因为它$scope是可用的controller.此外,虽然限定两个link和controller,一个确实需要小心关于两个的调用顺序(controller之前执行).
但是,为了与Angular方式保持一致,大多数DOM操作和双向绑定使用$watchers通常在link函数中完成,而子API和$scope操作的API在中完成controller.这不是一个硬性规则,但这样做会使代码更加模块化并有助于分离关注点(控制器将维护directive状态和link功能将保持DOM+外部绑定).
Rad*_*ler 17
的controller功能/对象表示一个抽象模型-视图-控制器(MVC).虽然没有什么新东西可以写MVC,但它仍然是角度最重要的优点:将问题分成更小的部分.就是这样,仅此而已,所以如果你需要对Model来自View这些工作Controller的合适人员作出反应.
关于link功能的故事是不同的,它来自不同的视角,然后是MVC.一旦我们想跨越controller/model/view (模板)的界限,这是非常重要的.
让我们从传递给link函数的参数开始:
function link(scope, element, attrs) {
Run Code Online (Sandbox Code Playgroud)
为了link进入上下文,我们应该提到所有指令都经历了这个初始化过程的步骤:编译,链接.Brad Green和Shyam Seshadri的书摘录Angular JS:
编译阶段(链接的姐妹,我们在这里提一下以获得清晰的图片):
在此阶段,Angular遍历DOM以识别模板中的所有已注册指令.对于每个指令,它然后根据指令的规则(模板,替换,转换等)转换DOM,并调用编译函数(如果存在).结果是编译模板函数,
链接阶段:
为了使视图动态化,Angular然后为每个指令运行链接函数.链接函数通常在DOM或模型上创建侦听器.这些侦听器始终使视图和模型保持同步.
link可以在此处找到如何使用的一个很好的示例:创建自定义指令.请参阅示例:创建操纵DOM的指令,该指令在页面中插入"日期时间",每秒刷新一次.
只是上面这个丰富资源的一个非常简短的片段,显示了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);
});
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
152794 次 |
| 最近记录: |