Sending event when AngularJS finished loading

2019-01-02 17:06发布

Wondered what's the best way to detect the finish of page loading/bootstrapping, when all directives done compiling/linking.

Any event already there? Should I overload the bootstrap function?

12条回答
梦寄多情
2楼-- · 2019-01-02 17:24

I had a fragment that was getting loaded-in after/by the main partial that came in via routing.

I needed to run a function after that subpartial loaded and I didn't want to write a new directive and figured out you could use a cheeky ngIf

Controller of parent partial:

$scope.subIsLoaded = function() { /*do stuff*/; return true; };

HTML of subpartial

<element ng-if="subIsLoaded()"><!-- more html --></element>
查看更多
泪湿衣
3楼-- · 2019-01-02 17:26

may be i can help you by this example

In the custom fancybox I show contents with interpolated values.

in the service, in the "open" fancybox method, i do

open: function(html, $compile) {
        var el = angular.element(html);
     var compiledEl = $compile(el);
        $.fancybox.open(el); 
      }

the $compile returns compiled data. you can check the compiled data

查看更多
荒废的爱情
4楼-- · 2019-01-02 17:27

According to the Angular team and this Github issue:

we now have $viewContentLoaded and $includeContentLoaded events that are emitted in ng-view and ng-include respectively. I think this is as close as one can get to knowing when we are done with the compilation.

Based on this, it seems this is currently not possible to do in a reliable way, otherwise Angular would have provided the event out of the box.

Bootstrapping the app implies running the digest cycle on the root scope, and there is also not a digest cycle finished event.

According to the Angular 2 design docs:

Because of multiple digests, it is impossible to determine and notify the component that the model is stable. This is because notification can further change data, which can restart the binding process.

According to this, the fact that this is not possible is one the reasons why the decision was taken to go for a rewrite in Angular 2.

查看更多
谁念西风独自凉
5楼-- · 2019-01-02 17:27

If you want to generate JS with server-side data (JSP, PHP) you could add your logic to a service, that will be loaded automatically when your controller is loaded.

Additionally, if you want to react when all directives are done compiling/linking, you could add the appropriate proposed solutions above in the initialization logic.

module.factory('YourControllerInitService', function() {

    // add your initialization logic here

    // return empty service, because it will not be used
    return {};
});


module.controller('YourController', function (YourControllerInitService) {
});
查看更多
浮光初槿花落
6楼-- · 2019-01-02 17:30

If you don't use ngRoute module, i.e. you don't have $viewContentLoaded event.

You can use another directive method:

    angular.module('someModule')
        .directive('someDirective', someDirective);

    someDirective.$inject = ['$rootScope', '$timeout']; //Inject services

    function someDirective($rootScope, $timeout){
        return {
            restrict: "A",
            priority: Number.MIN_SAFE_INTEGER, //Lowest priority
            link    : function(scope, element, attr){
                $timeout(
                    function(){
                        $rootScope.$emit("Some:event");
                    }
                );
            }
        };
    }

Accordingly to trusktr's answer it has lowest priority. Plus $timeout will cause Angular to run through an entire event loop before callback execution.

$rootScope used, because it allow to place directive in any scope of the application and notify only necessary listeners.

$rootScope.$emit will fire an event for all $rootScope.$on listeners only. The interesting part is that $rootScope.$broadcast will notify all $rootScope.$on as well as $scope.$on listeners Source

查看更多
与君花间醉酒
7楼-- · 2019-01-02 17:37

If you are using Angular UI Router, you can listen for the $viewContentLoadedevent.

"$viewContentLoaded - fired once the view is loaded, after the DOM is rendered. The '$scope' of the view emits the event." - Link

$scope.$on('$viewContentLoaded', 
function(event){ ... });
查看更多
登录 后发表回答