angular - ng-if - 如何在渲染ng-if模板后回调

时间:2014-06-26 18:28:30

标签: javascript jquery angularjs angularjs-directive angularjs-scope

在Angular中,我需要在加载了某个类的元素之后调用一个函数。 元素的显示通过ng-if =' expr'来控制。 $ scope.expr的值在某个ajax调用响应后设置。

现在,如果我尝试将$ watch放在expr上,或者使用$ evalAsync。它不起作用。可能是因为这些事件是在模板部分实际运行之前运行的。

以下是示例代码:http://jsbin.com/kuyas/1/edit 在这里,我需要一个关于ng的回调类型 - 如果在模板渲染后执行它。

4 个答案:

答案 0 :(得分:26)

一个可能的答案是创建一个执行任何你想做的指令。如果您只在ng-if控制的HTML部分中使用该指令,那么该指令将处于休眠状态,直到ng-if表达式为真。

那会做你想要的吗?

答案 1 :(得分:16)

问题是无法知道是否使用摘要循环完成了角度,确保所有元素都已渲染。

要解决此问题,有两个选项

  1. 将回调函数包装在指令中。在ng-if中包含该指令。并且只有当你想要执行回调时才使该表达式成为真实。
  2. 在内部调用您的回调函数setTimeOut(function(){ ... }, 0);,因为浏览器默认将所有事件保留在队列中,因此,当摘要循环运行时,您的回调函数将进入队列并在摘要循环结束后立即执行。

答案 2 :(得分:3)

我认为最简单的解决方案是执行以下操作:

<div ng-if="sectionActivated">
    <div ng-init="callBack()"></div>
</div>

仅当受ng-if影响的内容已被呈现时,才会调用您的回调。

答案 3 :(得分:1)

该指令可能如下所示:

import * as angular from 'angular';

class OnFinishRenderDirective implements angular.IDirective {

  public restrict = 'A';
  public replace = false;

  public link = (
    scope: any,
    // scope:        angular.IScope,
    element: angular.IAugmentedJQuery,
    attr: any,
    modelCtrl: any,
    link: angular.ITemplateLinkingFunction ) => {

    if ( scope.$last === true ) {
      this.$timeout(() => {
        scope.$emit( 'elementRendered' );
      } );
    }

  }

  constructor( private $timeout: angular.ITimeoutService ) { }

}

export function onFinishRenderFactory(): angular.IDirectiveFactory {

  var directive = ( $timeout: angular.ITimeoutService ) => new OnFinishRenderDirective( $timeout );
  directive.$inject = [ '$timeout' ];
  return directive;
}

您必须将其导入并添加到您的模块

import { onFinishRenderFactory } from './onFinishRender/onFinishRender.directive';

angular.module( 'yourModule', [] )
.directive( 'onFinishRender', onFinishRenderFactory() )

然后,您可以在标记的某处使用该指令,以在呈现指令时发出事件。

<div onFinishRender>I am rendered</div>

您甚至可以在指令DIV中添加一个额外的属性,然后您可以从链接函数中的ATTR对象中获取该属性,并添加到$ emit函数以识别要呈现的特定DIV。

这会回答你的问题吗?