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
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?
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.
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
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.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?