bagya bagya - 7 months ago 41
Javascript Question

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/

Answer

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.