Angular: running function in controller when all d

2020-03-30 06:04发布

I'm trying to come up with some code which allows me to run a function in the controller but only once the whole dom is setup and ready (including the directives link function run etc.).

I'm currently communicating between ctrl/service and the directive via $rootScope broadcasts. The first broadcast at the time of the controller loading is not being picked up by the directive. The reason is of course that the controller loads before the directive link function runs. I've read a few similar questions on SO where people recommended on using $timeout for these calls. This unfortunately doesn't always work and I don't want to clutter my ctrl/services with lots of $timeout calls. Therefore I'm looking for another solution to my problem.

Communication pattern is as follows:

1.) Controller tells Service to prepare some data (via function call in service)

2.) Service tells directive to display data (via broadcast)

3.) Directive displays data ...or not in my case :(

EDIT:

As timing is essential in my app, I'm basically looking for a way to initiate a function in the controller as soon as all angular components have finished loading. That function in the controller will display content by assigning a value to a scope variable. At the same time it will start taking the time. I can of course only start doing that once the directives are loaded, otherwise the tmining is wrong or the directive is not yet ready to display content etc.

I've read through a blog post by Ben Nadel, which basically shows how directives are loaded. I was hoping to setup an outer directive which loads last so I can trigger the finished loading from there. Unfortunately that doesn't work as soon as any of the inner directives use a templateUrl. http://www.bennadel.com/blog/2603-directive-controller-and-link-timing-in-angularjs.htm

1条回答
我只想做你的唯一
2楼-- · 2020-03-30 06:21

Using $timeout would be terrible. Don't do that. You can't define how long a server call is going to take.

I would recommend using this pattern:

  • Have the controller use a service to load some data, and have the promise in the controller assign the return data to a scope variable.
  • Pass that scope variable into your directive.
  • Setup a watch in the directive link function, when it loads it will go from undefined to desired value. Done!

// in your controller

YourService.all().then(function(data) {
  $scope.data = data;
});

// in your view

<some-directive your-data="data"></some-directive>

// in your directive

angular.module('blah.directives').directive('someDirective', function() {
    return {
      scope: {
        yourData: '='
      },
      link: function(scope, element, attrs) {

        var watcher = scope.$watch('yourData', function() {
          if(scope.yourData === undefined) return;

          // at this point your data will be loaded, do work

          // optionally kill watcher at this point if it's not going to update again
          watcher();
        });
      }
    }
  });
查看更多
登录 后发表回答