angular - ng-if - how to callback after ng-if template has been rendered

旧城冷巷雨未停 提交于 2019-12-09 14:18:36

问题


in Angular, I need to call a function after an element with certain class has been loaded. Display of the element is controlled via ng-if='expr'. Value of $scope.expr is set after some ajax call has responded.

Now, if I try putting $watch on expr, or using $evalAsync. it is not working. probably the reason being that these events are run before the template part actually runs.

Here is a sample code : http://jsbin.com/kuyas/1/edit Here I need a callback sort of thing on ng-if that gets executed after the template has rendered.


回答1:


One possible answer would be to create a directive that does whatever you want to do. If you then use that directive only within the section of HTML controlled by the ng-if, then the directive will be dormant until the ng-if expression is true.

Would that do what you want?




回答2:


Problem was that there is no way to know if angular is done with the digest loop, ensuring that all elements have been rendered.

To solve this issue, there were two options

  1. Wrap your callback function in a directive. include that directive in ng-if. and make that expression true only when u want your callback to be executed.
  2. Call your callback function inside, setTimeOut(function(){ ... }, 0); as browsers by default keep all events in a queue, therefore, when digest loop is running, your callback function will enter the queue and get executed as soon digest loop is over.



回答3:


Simplest solution in my view is to do the following:

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

Your callback will be called only when what is affected by ng-if has been rendered.




回答4:


The directive could look something like this:

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;
}

You would have to import it and add to your module

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

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

Then you can use the directive somewhere in your markup to emit the event when the directive has been rendered.

<div onFinishRender>I am rendered</div>

You could even add an extra attribute in the directive DIV which you can then grab from the ATTR object in the link function and add to your $emit function to identify this specific DIV to be rendered.

Does that answer your question?



来源:https://stackoverflow.com/questions/24437658/angular-ng-if-how-to-callback-after-ng-if-template-has-been-rendered

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!