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

前端 未结 4 1232
再見小時候
再見小時候 2021-02-18 18:47

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 a

相关标签:
4条回答
  • 2021-02-18 19:12

    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?

    0 讨论(0)
  • 2021-02-18 19:16

    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.

    0 讨论(0)
  • 2021-02-18 19:18

    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.
    0 讨论(0)
  • 2021-02-18 19:20

    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?

    0 讨论(0)
提交回复
热议问题