【发布时间】:2016-03-10 06:21:22
【问题描述】:
如何在渲染模板后运行方法$scope.myWork()?我想设置$scope.value,然后我需要用 JQuery 改变一些东西(例如在模板内容的 DOM 中)。 $scope.$watch('value', function (){....}) 正在“在”渲染之前工作(模板的 DOM 尚不可用)。谢谢。
【问题讨论】:
标签: angularjs
如何在渲染模板后运行方法$scope.myWork()?我想设置$scope.value,然后我需要用 JQuery 改变一些东西(例如在模板内容的 DOM 中)。 $scope.$watch('value', function (){....}) 正在“在”渲染之前工作(模板的 DOM 尚不可用)。谢谢。
【问题讨论】:
标签: angularjs
【讨论】:
$anchorScroll 是否可以完成这项工作或为此创建服务(以使您的控制器更具可测试性)。制作一个指令,将 div 的实际“顶部”设置为控制器中的变量和滚动的服务将是一个很好的匹配。
require: '^DIVdirectiveName' 来获取控制器。看到这个更新小提琴jsfiddle.net/C6SUv/8
我在属性指令中使用terminal 和transclude 在模型更新并呈现视图后调用作用域方法(在我的例子中是在$Resource.query 之后调整iframe 的大小):
.directive('postRender', [ '$timeout', function($timeout) {
var def = {
restrict : 'A',
terminal : true,
transclude : true,
link : function(scope, element, attrs) {
$timeout(scope.resize, 0); //Calling a scoped method
}
};
return def;
}])
$timeout 是黑魔法。 应该可以将JS方法声明为属性值并$parse它。
所以我在ng-repeat 中使用它(在我的例子中,树是递归渲染的):
<div post-render ng-repeat="r in regions | orderBy:'name'" ng-include="'tree_region_renderer.html'">
【讨论】:
我也遇到了这个问题,其他解决方案对我来说效果不佳,看起来 Protractor 必须解决的那种事情。对Protractor's client-side scripts 的快速回顾表明它使用angular.getTestability(element) 来了解何时实际运行测试。该方法一直等待,直到没有挂起的超时或 http 请求,然后运行您的回调。这是我的指令:
export function afterRender ($timeout) {
"ngInject";
return {
restrict: 'A',
terminal: true,
link: function (scope, element, attrs) {
angular.getTestability(element).whenStable(function() {
console.log('[rendered]');
});
}
};
}
【讨论】:
$browser 并使用其 notifyWhenNoOutstandingRequests() 方法注册一个回调。但请注意,这依赖于一些未记录的私有 API,可能会在没有通知的情况下中断。
Jens 上面的回答会起作用,但请注意,在较新的 AngularJS 版本(例如 1.2.3)上,您不能将 postRender 指令与 ng-repeat 结合为同一标签上的属性,因为它们都具有 transclude: true。在这种情况下,您必须删除 transclude 或使用带有 postRender 指令属性的单独标记。
使用终端时还要注意属性的优先级:true,因为您最终可能会因为同一标签上的优先级更高而导致属性无效。
【讨论】:
我在寻找一种分析 DOM 渲染的方法时发现了这个页面。我找到了一个非常简单的解决方案,适用于我的用例。
将 ng-init 处理程序附加到 DOM 元素并在处理程序函数中,使用 $timeout 来产生执行。示例:
HTML:
<div ng-init="foo()">
JS:
$scope.foo = function() {
$timeout(function() {
// This code runs after the DOM renders
});
});
【讨论】: