angularjs – 为什么ng-repeat改变了链接函数执行的顺序
在嵌套指令上执行编译和链接函数的通常顺序如下
标记 <dir1> <div dir2=""> </div> </dir1> 执行顺序 1) compile of directive 1 2) compile of directive 2 3) link of directive 2 4) link of directive 1 假设dir1将restrict属性设置为’E’,dir2将restrict设置为’A’ 现在,如果在同一标记中使用ng-repeat指令,则执行顺序会发生变化 标记 <dir1> <div ng-repeat="item in items"> <div dir2=""> </div> </div> </dir1> 假设项目是在范围上定义的,执行顺序将更改为 1) compile of directive 1 2) link of directive 1 3) compile of directive 2 4) link of directive 2 Plunker – https://plnkr.co/edit/fRGHS1Bqu3rrY5NW2d97?p=preview 为什么会这样?是因为ng-repeat已将transclude属性设置为element.如果是这种情况,为什么它应该改变dir1的执行顺序,这是在ng-repeat之外. 任何帮助将非常感激. 解决方法
首先,好问题!我曾经使用angular来开发几个webapps,但我从来没有意识到这一点.
这是因为在ngRepeat实施内部,谷歌团队使用了 然后你可以写下你自己的ngRepeat版本.我们称之为myRepeat. //mock ng-repeat : ) app.directive('myRepeat',function ($compile) { return { restrict:'A',transclude: 'element',priority: 1000,terminal: true,$$tlb: true,compile: function ($element,$attr) { var expression = $attr.myRepeat; var ngRepeatEndComment = $compile.$$createComment('end myRepeat',expression); //parse the ngRepeat expressions. var match = expression.match(/^s*([sS]+?)s+ins+([sS]+?)(?:s+ass+([sS]+?))?(?:s+tracks+bys+([sS]+?))?s*$/); var rhs = match[2]; //this would get items in your example return function ($scope,$element,$attr,ctrl,$transclude) { //$watch $scope[rhs] which rhs would be items in your example. $scope.$watchCollection(rhs,function myRepeatAction(collection) { $transclude(function(clone,scope) { clone[clone.length++] = clone; //append element }); }); } } } }); 如果注释掉watchCollection语句,您将获得第一个示例的输出.你可以用setTimeout替换$watchCollection来重现相同的日志. 如果我们查看angular.js的源代码,callstack就像watchCollection => $watch => $evalAsync => $browser.defer =>的setTimeout $watch source code. $browser.defer source code. 希望这能解决你的问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |