bagya
bagya

Reputation: 397

How to call the controller method after directive render using $timeout?

I need to call one function after directive render. Actually i tried using $timeout function. But it's not working.

HTML Code:

<div ng-app='myApp' ng-controller='module-menu-controller'>
    <layout-render></layout-render>
    <div after-grid-render="getGridObject()"></div>
</div>

JS Code:

var app = angular.module("myApp", []);

app.controller("module-menu-controller", function($scope, $compile) {

        $scope.getGridObject = function() {
            alert("After render");
        };
    });
app.directive("layoutRender", function() {
    return {
        restrict : "E",
        template : "<h1>Testing</h1>"
    };
});

app.directive('afterGridRender', ['$timeout', function ($timeout) {
        var def = {
            restrict: 'A',
            terminal: true,
            transclude: false,
            link: function (scope, element, attrs) {
                $timeout(scope.$eval(attrs.getGridObject),0);  //Calling a scoped method
            }
        };
        return def;

}]);

JS Fiddle Link: https://jsfiddle.net/bagya1985/k64fyy22/1/

Upvotes: 0

Views: 1240

Answers (2)

Kevin
Kevin

Reputation: 2893

Try this? Simple and clear

HTML

<div ng-app='myApp' ng-controller='module-menu-controller'>
    <grid after-grid-render="getGridObject"></grid>
</div>

JS

var app = angular.module("myApp", []);

app.controller("module-menu-controller", function($scope) {
        $scope.getGridObject = function() {
            alert("After render");
        };    
});

app.directive("grid", function($timeout) {
    return {
        restrict : "E",
        template : "<h1>Testing</h1>",
        scope:{
            afterGridRender:'='
        },
        link: function (scope, element, attrs) {
                $timeout(scope.afterGridRender(),0);  //Calling a scoped method
          }
    };
});

JSFiddle: https://jsfiddle.net/6o62kx3e/


Update

Do you mean you want it to be an attribute?

How about this one: https://jsfiddle.net/rt747rkk/

HTML

<div ng-app='myApp' ng-controller='module-menu-controller'>
    <my-directive a='5' after-grid-render="getGridObject"></my-directive>
</div>

<script type="text/ng-template" id="myDirectiveTemplate.html">
   <div> {{a}} {{b}} </div>
</script>

JS

var app = angular.module("myApp", []);

app.controller("module-menu-controller", function($scope) {
        $scope.getGridObject = function() {
            alert("After render");
        };    
});


app.directive('myDirective',  function () {
        return {
            restrict: 'E',
                replace: true,
            templateUrl:"myDirectiveTemplate.html",
            scope:{
                    a:'='
            },
            link: function (scope, element, attrs) {
                    scope.b=123;
                scope.gridObject="my grid object here";
            }
        };
});

app.directive('afterGridRender', ['$timeout', function ($timeout) {
        var def = {
            restrict: 'A',
            transclude: false,
            link: function (scope, element, attrs) {
                $timeout(function(){
                    scope.getGridObject();
                  alert(scope.$$childHead.gridObject);
                });
                        }
        };
        return def;
}]);

I'm not really sure what you want to do.

If you want the attribute directive to access the scope of the element (as shown in the second alert box in the example), I don't think there's an elegant way. One way is to use scope.$$childHead, it works but variables prefixed with $$ are angular internal variables and we should not use them generally speaking.

Upvotes: 1

Tarun Dugar
Tarun Dugar

Reputation: 8971

Here's a working fiddle.

Just have an additional attribute on the directive with the function:

HTML:

<div after-grid-render fnc="getGridObject()"></div>

Directive:

$timeout(scope.$eval(attrs.fnc),0);

Upvotes: 2

Related Questions