想要在菜单显示之前使用ui-router在AngularJS中运行一些初始化代码

时间:2014-12-21 15:50:25

标签: angularjs angular-ui-router

我想在实际菜单显示之前运行一些初始化代码。也就是说,在我的真实应用程序中,我有一个我想要加载的http资源,它将影响菜单选项列表中显示的选项。更具体地说,我想在我的程序第一次运行时发出“等待”消息,直到http资源完全加载。我一直在解决问题,但这似乎只在菜单加载后帮助我。

我希望不必使用引导程序模式,因为我想在我的应用程序中的多个位置执行此操作,而不仅仅是第一次运行。我也不是引导模式的忠实粉丝。对我来说似乎有点做作。

我试图用一个非常简单的例子来做到这一点,首先我已经加载到这里:

http://plnkr.co/edit/eehhA1CR2sEMQZrQBo3E?p=preview

var app = angular.module('svccApp', [
    'ui.router'
]);


app.config(['$stateProvider', '$urlRouterProvider',

    function ($stateProvider, $urlRouterProvider,$q,$timeout) {
        $urlRouterProvider.otherwise('/');

        $stateProvider
            .state('home', {
                url: '/',
                template: '<p>HOME HERE</p>',
                controller: 'HomeController as vm'
            }).
            state('about', {
                url: '/about',
                template:   '<p>about here title: {{vm.title}}</p>',  //'index4template.html',
                controller: 'AboutController as vm',

                resolve: {
                    title: function(){
                        return 'from title function';
                    }
                }
            });
    }]);


var injectParamsAbout = ['title'];
var AboutController = function (title) {
    var vm = this;
    vm.title = title;
};
AboutController.$inject = injectParamsAbout;
angular.module('svccApp').controller('AboutController', AboutController);

var injectParamsHome = [];
var HomeController = function () {
};
HomeController.$inject = injectParamsHome;
angular.module('svccApp').controller('HomeController', HomeController);

2 个答案:

答案 0 :(得分:3)

如何使用父母和孩子(不确定这不是你不喜欢的引导模式)。我创建/更新了working plunker here

// this is loaded immediately
// and that means, that user will see ...loading... ASAP
.state('about', {
    url: '/about',
    template:   '<p ui-view="">...loading...</p>',  //'index4template.html',
    controller: function($state){ $state.go("about.child"); },
    //controller: 'AboutController as vm',
})

// this state is triggered in the controller above
// and it will take 2,5 second to do all the resolve stuff
.state('about.child', {
    template:   '<p>about here title: {{vm.title}}</p>',  
    controller: 'AboutController as vm',
    resolve: {
        title: function($timeout){
            return $timeout(function(){
               return 'from title function';
            }
            , 2500 // wait 2,5 second - and then replace ...loading...
            );
        }
    }

背后的想法是加载一些模板 (例如...loading...作为父视图。一旦实例化(显示加载),我们将重定向到我们的孩子。在上面的示例中,有2.5秒的延迟(加载表单服务器),然后子项完全替换父...

检查here

答案 1 :(得分:0)

基于@Radim的例子,一个更清晰的方法对我有用:

如果您使用的是ui-router,则可以使用嵌套状态解决此问题。例如:

$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'
    });

在此示例中,您已定义了3条路线:&#34; /&#34;,&#34; / landing&#34;,&#34; / profile&#34;

因此,即使用户直接进入/登陆或/ profile

,也会始终调用InitController(与&#34; /&#34;路由相关)

重要提示:请勿忘记在此部分中加入<div ui-view></div>以启用子状态控制器加载