如何在dom完成渲染后运行指令?

我看到一个看似简单的问题(通过阅读Angular JS文档)解决scheme。

我有一个Angular JS指令,它根据其他DOM元素的高度进行一些计算,以定义DOM中容器的高度。

在这个指令里面有类似的东西:

return function(scope, element, attrs) { $('.main').height( $('.site-header').height() - $('.site-footer').height() ); } 

问题是当指令运行时, $('site-header')找不到,返回一个空数组,而不是我需要的jQuery包装的DOM元素。

是否有一个callback,我可以在我的指令中使用,只有在加载DOM后运行,我可以通过正常的jQueryselect器样式查询访问其他DOM元素?

这取决于你的$('site-header')是如何构build的。

您可以尝试使用$超时延迟0。 就像是:

 return function(scope, element, attrs) { $timeout(function(){ $('.main').height( $('.site-header').height() - $('.site-footer').height() ); }); } 

解释它是如何工作的: 一 , 二 。

不要忘记在你的指令中注入$timeout

 .directive('sticky', function($timeout) 

可能作者不会再需要我的答案了。 不过,为了完整起见,我觉得其他用户可能会觉得它有用。 最好也是最简单的解决方法是在返回函数体内使用$(window).load() 。 (或者你可以使用document.ready ,这取决于你是否需要所有的图像)。

在我看来,使用$timeout是一个非常弱的选项,在某些情况下可能会失败。

这里是我将使用的完整代码:

 .directive('directiveExample', function(){ return { restrict: 'A', link: function($scope, $elem, attrs){ $(window).load(function() { //...JS here... }); } } }); 

下面是我如何做到这一点:

 app.directive('example', function() { return function(scope, element, attrs) { angular.element(document).ready(function() { //MANIPULATE THE DOM }); }; }); 

有一个ngcontentloaded事件,我认为你可以使用它

 .directive('directiveExample', function(){ return { restrict: 'A', link: function(scope, elem, attrs){ $$window = $ $window init = function(){ contentHeight = elem.outerHeight() //do the things } $$window.on('ngcontentloaded',init) } } }); 

如果由于外部资源而无法使用$ timeout,并且由于特定的时间问题而无法使用指令,请使用广播。

添加$scope.$broadcast("variable_name_here"); 在所需的外部资源或长时间运行的控制器/指令完成之后。

然后在加载外部资源后添加下面的内容。

 $scope.$on("variable_name_here", function(){ // DOM manipulation here jQuery('selector').height(); } 

例如在延迟HTTP请求的承诺。

 MyHttpService.then(function(data){ $scope.MyHttpReturnedImage = data.image; $scope.$broadcast("imageLoaded"); }); $scope.$on("imageLoaded", function(){ jQuery('img').height(80).width(80); } 

我有一个类似的问题,并希望在这里分享我的解决scheme。

我有以下的HTML:

 <div data-my-directive> <div id='sub' ng-include='includedFile.htm'></div> </div> 

问题:在父div的指令的链接函数中,我想要jquery的子div#sub。 但是它只是给了我一个空的对象,因为ng-include在指令的链接函数运行的时候还没有完成。 所以首先我用$超时做了一个肮脏的解决方法,这工作,但延迟参数取决于客户端速度(没有人喜欢)。

工作,但肮脏:

 app.directive('myDirective', [function () { var directive = {}; directive.link = function (scope, element, attrs) { $timeout(function() { //very dirty cause of client-depending varying delay time $('#sub').css(/*whatever*/); }, 350); }; return directive; }]); 

这是干净的解决scheme:

 app.directive('myDirective', [function () { var directive = {}; directive.link = function (scope, element, attrs) { scope.$on('$includeContentLoaded', function() { //just happens in the moment when ng-included finished $('#sub').css(/*whatever*/); }; }; return directive; }]); 

也许这对别人有帮助