【问题标题】:angular - ng-if - how to callback after ng-if template has been renderedangular - ng-if - 如何在 ng-if 模板渲染后回调
【发布时间】:2014-06-26 18:28:30
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    这会满足你的要求吗?

    【讨论】:

    • 我喜欢这个。我创建了一个 IAmRendered 组件,它将响应 $OnInit() 以进行渲染,并响应 $OnDestroy() 以进行葬礼!很好的建议。
    • @Mattijs,我们如何在 angular1 中做到这一点
    • @SukeshChand 在下面查看我的答案
    【解决方案2】:

    问题是没有办法知道 angular 是否使用摘要循环完成,以确保所有元素都已渲染。

    要解决这个问题,有两种选择

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

    【讨论】:

    • 我更喜欢这个带有 setTimeout 的解决方案,允许我做一些不是页面上的小部件或限制在 ng_if 内的事情
    • setTimeout(function(){ // do whatever }, 0); 这是完美的。谢谢!
    【解决方案3】:

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

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

    只有在受ng-if 影响的内容已呈现时才会调用您的回调。

    【讨论】:

    • 这部分对我有用,但使用setTimeout(function(){ // do whatever }, 0); 也是因为有一些自定义元素尚未准备好,因为我试图禁用它们,所以对于那些自定义元素我使用 set timeout after 5 秒的页面加载以禁用它们
    【解决方案4】:

    指令可能如下所示:

    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。

    这是否回答了您的问题?

    【讨论】:

      猜你喜欢
      • 2020-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      • 2017-12-11
      相关资源
      最近更新 更多