[英]Angular directive's link function won't manipulate DOM
I'm trying to access data from a service so I can manipulate an ngRepeat
ed list with jQuery. 我正在尝试从服务访问数据,以便可以使用jQuery处理ngRepeat
ed列表。 I cannot get the link
function to work. 我无法使link
功能正常工作。 Based on what I've read, I would expect that in either 根据我所读的内容,我希望无论哪种方式
app.directive('myDir', function() {
return {
restrict: 'E',
templateUrl: 'url.html',
link: function(scope, el, attrs) {
//jQuery to manipulate DOM here
}
};
});
or 要么
app.directive('myDir', function() {
return {
restrict: 'E',
templateUrl: 'url.html',
compile: function(scope, el, attrs) {
return {
post: function() {
//jQuery to manipulate DOM here
}
}
}
}
});
But the elements are not on the page yet, so it does not work. 但是元素尚未在页面上,因此它不起作用。 What am I missing? 我想念什么?
Try waiting one $digest phase. 尝试等待一个$ digest阶段。 This will give enough time to the ng-repeat
to render the DOM elements. 这将为ng-repeat
提供足够的时间来呈现DOM元素。 You can use $timeout for that. 您可以使用$ timeout。
link: function(scope, el, attrs) {
$timeout(function() {
//jQuery to manipulate DOM here
});
}
Check the example below. 检查以下示例。 Here we have my-dir
collecting all the elements created by the ng-repeat
. 在这里,我们有my-dir
收集ng-repeat
创建的所有元素。 There is a helper mockup-box
inner directive that include my-dir
parent directive controller and registers itself ( its element ) using its methods. 有一个帮助程序mockup-box
内部指令,该指令包括my-dir
父指令控制器,并使用其方法注册自身( 其元素 )。
Then my-dir
controller calls the invalidateChildren function which waits for the children directive to accumulate by delaying the validateChildren
function execution. 然后, my-dir
控制器调用invalidateChildren函数,该函数通过延迟validateChildren
函数的执行来等待children指令的累积。
In the validateChildren
function we manipulate the DOM elements and we are sure that they'll be there because each one registers only when it's compiled. 在validateChildren
函数中,我们操作DOM元素,并确保它们会在那里,因为每个元素仅在编译时才注册。 There is some dummy code in validateChildren function but you can place anything there. validateChildren函数中有一些伪代码,但您可以在其中放置任何内容。
There is another added benefit. 还有另外一个好处。 We no longer depend on the ng-repeat nor does my-dir knows how the child elements will be created. 我们不再依赖ng-repeat,也不知道my-dir将如何创建子元素。 They might even be "static" children. 他们甚至可能是“静态”孩子。 It also supports adding additional children. 它还支持添加其他子代。 If the ng-repeat generates additional elements they'll again register in the parent controller and invoke the validateChildren function. 如果ng-repeat生成其他元素,它们将再次在父控制器中注册并调用validateChildren函数。
angular.module('example', []) .controller('AppCtrl', function($scope) { $scope.mockupData = ['a', 'b', 'c', 'd'] }) .directive('myDir', function() { return { controller: function($element, $timeout) { var ctrl = this; var childrenDirty = false; this.children = []; this.addChild = function(jqChild) { ctrl.children.push(jqChild); ctrl.invalidateChildren(); }; this.removeChild = function(jqChild) { var index = ctrl.children.indexOf(jqChild); if (index >= 0) { ctrl.children.splice(index, 1); } }; this.invalidateChildren = function() { if (!childrenDirty) { childrenDirty = true; $timeout(ctrl.validateChildren); } }; this.validateChildren = function() { childrenDirty = false; // Will be fire only once angular.forEach(ctrl.children, function(jqChild) { jqChild.html('value: "' + jqChild.html() + '"'); }); }; }, link: function() { } } }) .directive('mockupBox', function() { return { require: '^myDir', link: function(scope, iElement, iAttrs, myDirCtrl) { myDirCtrl.addChild(iElement); scope.$on('$destroy', function() { myDirCtrl.removeChild(iElement); }); } }; });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="example" ng-controller="AppCtrl"> <div my-dir> <div ng-repeat="data in mockupData" mockup-box>{{data}}</div> </div> </div>
mockupData
value is ['a', 'b', 'c', 'd']; mockupData
值为['a','b','c','d']; validateChildren
function edits the child elements content and adds "value:" in front. validateChildren
函数编辑子元素的内容,并在前面添加“ value:”。 The result from the code execution will be value: "<letter>"
for every child element. 代码执行的结果将是每个子元素的value: "<letter>"
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.