AngularJS:渲染后回调(渲染后使用DOM)

时间:2012-08-14 13:29:06

标签: angularjs

如何在渲染模板后运行方法$scope.myWork()?我想设置$scope.value,然后我需要用JQuery改变一些东西(例如在模板内容的DOM中)。 $scope.$watch('value', function (){....})正在“之前”渲染(模板的DOM尚未可用)。感谢。

5 个答案:

答案 0 :(得分:18)

创建一个在链接函数中运行代码的directive。 构建模板后调用链接函数。

请参阅ng-click以获取相关信息。

答案 1 :(得分:16)

我在属性指令中使用terminaltransclude来在更新模型并呈现视图后调用作用域方法(在我的情况下,在$ 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方法声明为属性值并$解析它。

所以我在ng-repeat中使用它(在我的例子中,树是递归渲染的):

<div post-render ng-repeat="r in regions | orderBy:'name'" ng-include="'tree_region_renderer.html'">

答案 2 :(得分:8)

我也有这个问题,其他解决方案对我来说效果不好,看起来像是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]');
        });
      }
  };
}

答案 3 :(得分:2)

上面的Jens回答可行,但请注意,在较新的AngularJS版本(例如1.2.3)中,您不能将该postRender指令与ng-repeat结合使用作为同一标记上的属性,因为它们都具有transclude:true。在这种情况下,您必须删除transclude或具有postRender指令属性的单独标记 使用terminal时也要注意属性的优先级:true,因为由于同一标记上的优先级较高,最终可能会使属性无效。

答案 4 :(得分:-1)

在寻找剖析DOM渲染的方法时,我找到了这个页面。我发现了一个非常简单的解决方案,它适用于我的用例。

将ng-init处理程序附加到DOM元素并在处理程序函数中,使用$ timeout来执行。例如:

HTML:

Uncaught SyntaxError: Missing initializer in const declaration

JS:

(function(){
  const foo = 1;
  const bar = foo;
}());