AngularJS - load data before loading any controlle

2019-05-11 00:41发布

问题:

I'm making a single page application (SPA). I made a controller called InitialControler to load the data from the server at this url (local.app/init).

I want this url to be opened before any other url. I'm using ui-router, I did a $state.go('init') in the .run() function but it still load the requested page before the 'init' page

回答1:

One way to do is, in config declare only 'init' state. And in InitialController, after data is loaded(resolve function of service call), configure other states. But in this approach, whenever you refresh the page, the url will change to local.app.init.

To stay in that particular state even after reloading, the solution I found is to have a StartUp app in which I loaded the required data and after that I bootstraped the main app manually by angular.bootstrap.



回答2:

First create state called app

$stateProvider.state('app', {
    abstract:    true,
    templateUrl: "assets/partials/container.html",
    controller:  'AppCtrl',
    resolve: {
        init: function(MyFactory) {
            return MyFactory.resolver();
        }
    }
});

Now, any new state you create should be child state of app state. This is also good because it become sort of your root scope. And state will not process unless your factory resolves.

This is how you create your factory

app.factory('MyFactory', function($http){
    var items = [];
    return {
        resolver: function(){
            return $http.get('my/api').success(function(data){
                items = data;
            })
        },
        get() {
            return items;
        }
    }
});

Now in any other state

$stateProvider.state('app.items', {
    url:    '/items',
    templateUrl: "assets/partials/items.html",
    controller:  function($scope, MyFactory){
        $scope.items = MyFactory.get();
    }
});

More on sate resolve

https://github.com/angular-ui/ui-router/wiki#resolve



回答3:

If you are using ui-router then you could resolve this using nested states. For example:

$stateProvider
    .state("main", {
        url: "/",
        template: '<div ui-view></div>',
        controller: 'InitController'
    })
    .state("main.landing", {
        url: "landing",
        templateUrl: "modules/home/views/landing.html",
        controller: 'LandingPageController'
    })
    .state("main.profile", {
        url: "profile",
        templateUrl: "modules/home/views/profile.html",
        controller: 'ProfileController'
    });

In this example you have defined 3 routes: "/", "/landing", "/profile"

So, InitController (related to "/" route) gets called always, even if the user enters directly at /landing or /profile

Important: Don't forget to include <div ui-view></div> to enable the child states controller load on this section