我有一个看似简单的问题,没有明显的(通过阅读 Angular JS 文档)解决方案。
我有一个 Angular JS 指令,它根据其他 DOM 元素的高度进行一些计算,以定义 DOM 中容器的高度。
指令内部正在发生类似的事情:
return function(scope, element, attrs) {
$('.main').height( $('.site-header').height() - $('.site-footer').height() );
}
问题是当指令运行时,$('site-header')
找不到,返回一个空数组而不是我需要的 jQuery 包装的 DOM 元素。
是否有我可以在我的指令中使用的回调,它只在 DOM 加载后运行并且我可以通过正常的 jQuery 选择器样式查询访问其他 DOM 元素?
这是我的做法:
app.directive('example', function() {
return function(scope, element, attrs) {
angular.element(document).ready(function() {
//MANIPULATE THE DOM
});
};
});
element.ready(function(){
可能作者不再需要我的答案了。尽管如此,为了完整起见,我觉得其他用户可能会觉得它很有用。最好和最简单的解决方案是在返回函数的主体内使用 $(window).load()
。 (或者您可以使用 document.ready
。这真的取决于您是否需要所有图像)。
在我看来,使用 $timeout
是一个非常弱的选项,在某些情况下可能会失败。
这是我要使用的完整代码:
.directive('directiveExample', function(){
return {
restrict: 'A',
link: function($scope, $elem, attrs){
$(window).load(function() {
//...JS here...
});
}
}
});
有一个 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)
}
}
});
$ $window
在做什么吗?
如果由于外部资源而无法使用 $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);
}
我遇到了类似的问题,想在这里分享我的解决方案。
我有以下 HTML:
<div data-my-directive>
<div id='sub' ng-include='includedFile.htm'></div>
</div>
问题:在父 div 指令的链接函数中,我想对子 div#sub 进行 jquery。但它只是给了我一个空对象,因为当指令的链接功能运行时 ng-include 还没有完成。所以首先我用 $timeout 做了一个肮脏的解决方法,它有效,但延迟参数取决于客户端速度(没有人喜欢这样)。
工作但很脏:
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;
}]);
这是干净的解决方案:
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;
}]);
也许它可以帮助某人。
$timeout
传递给指令。多哈。现在一切正常,干杯。$timeout
传递给这样的指令:.directive('sticky', function($timeout) { return function (scope, element, attrs, controller) { $timeout(function(){ }); }); };