0

So, we have a directive grid, which exposes directive controller to the angular controller, so that controller can call functions on directive (just like a form controller).

Now, in my angular controller every thing works as long as I access the directive controller from a callback action eg. some $scope.xx which are called on some event like click or any thing.

But when i try to access the directive controller at controller initialization time, the directive controller is undefined, that means, directives link function is not called yet.

Here's some code

function controller() {
  $scope.init = function() {
    $scope.grid.search(xx)
  }

$scope.init() // this will fail, because $scope.grid is undefined.

$scope.onClick = function() {
  $scope.grid.search(xx) // this will work
 }
}

is there any other way, other then watching the $scope.grid, to have the $scope.grid.search called on controller initialization

7
  • angular cycle, it will first execute your controller then your generate html as per your controller scope. So in you case you will not have grid object in your controller scope. You should let angular execute one digest cycle before calling $scope.grid.search() . You can use $timeout for that. Commented Jan 27, 2015 at 15:26
  • This breaks separation of concerns, in my opinion, when you make assumptions in your controller about an existence of a directive. Granted, tt's indirect here via scope, but it still feels wrong. $modal solved that with the use of a service to call functions on the $modal Commented Jan 27, 2015 at 15:33
  • I still dont understand what you mean by $modal Commented Jan 27, 2015 at 15:41
  • why can't you pass a config object to the directive for initialization purposes? Commented Jan 27, 2015 at 15:43
  • 1
    I honestly don't think this is the way to achieve anything. I don't remember I see anyone use this way, calling function in the directive. It just feels wrong to me. Maybe you should talk more about why do you want to do it ? Commented Jan 27, 2015 at 15:49

2 Answers 2

2

You can just broadcast event from link function in your directive.

<div ng-controller="MyCtrl">
    <div abc></div>
</div>

myApp.directive('abc', function($rootScope) {
    return {
        restrict: "EA",
        link: function(scope, element, attrs){
            $rootScope.$broadcast("initialize");
        }
    }
});

function MyCtrl($scope) {
    $scope.$on("initialize", function(){
        alert("Link function has been initialized!");
    });
}

I've created JSFiddle for you.

Sign up to request clarification or add additional context in comments.

2 Comments

This could be a possible solution.
This will absolutely work, but doesnt look clean to me, i can change this directive as i have access to it, but if it was a third party directive, this wouldnt be a solution. Looks like i will go with $watch, doesnt look like there's any better solution at this time.
0

The problem is that parent controllers are always called before child controllers.

If you want to run code after your child directive is initialized, you can create a directive and put the initialization code inside of its link function.

This works because parent link functions are always called after child link (and controller) functions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.