uiRouter中的异步templateProvider

时间:2016-02-18 16:57:22

标签: angularjs angular-ui-router

结束了一个小问题。 在我的UI.state提供程序中,我想使用一个函数来获取基于用户访问的菜单,用户访问权限将由API调用确定。

到目前为止一切都很好,有一个restangular调用获取信息并根据返回生成一个菜单(使用md按钮)。我的问题是,如何让templateProvider接受输入。 以下是路由不工作时的代码。

====================简单(和破碎)示例===================== =======

$stateProvider
    .state('index', {
        url: "/index",
        views: {
            main: {templateUrl: "page/welcome"},
            menu: {
                templateProvider:
                    function ($http, $stateParams, accessFactory) {
                        return accessFactory.getMenu('home', function(menu){
                            console.log("Got back " + menu);
                            return menu;
                        });
                        //return '<md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button>';

                    }
            }
        }

    })

所以我检查过的事情。

  1. 响应有效,我们该函数的行呈现按钮(没有调用函数的测试返回是“返回”+菜单的副本
  2. 如果我不调用该函数并只是返回,我会得到按钮
  3. 如果我将其更改为对只返回字符串的函数的调用,则可以正常工作。
  4. 这是不起作用的功能

    knowledge.factory('accessFactory', ['$http', "Restangular", '$timeout', function($http, Restangular, $timeout) {
        var service = Restangular.service("access");
        var userAccess=null;
        service.getMyAccess = function(callback) {
            service.one('list').one('me').get().then(function(data){
                userAccess = data;
                callback(userAccess)
            })
        }
        service.MyAccess = function(callback){
            if(userAccess === null ){
                service.getMyAccess(function(data){
                    callback(userAccess);
                })
            } else {
                callback(userAccess);
            }
        }
    
    
       service.getMenu = function(menutype, callback){
    
    
            if (menutype === 'login'){
                callback('<md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Login" ui-sref="login"><md-icon md-svg-src="/images/icons-svg/unlock.svg" class="svg-icon" style="color: rgb(0, 0, 0);"></md-icon> </md-button>');
    
    //            return '<md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Login" ui-sref="login"><md-icon md-svg-src="/images/icons-svg/unlock.svg" class="svg-icon" style="color: rgb(0, 0, 0);"></md-icon> </md-button><md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button><md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button><md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button><md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button><md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button>';
            } else if(menutype === 'home'){
                callback('<md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button>');
            }
    

    如果我将其更改为只返回相同的字符串,则会中断。有什么想法吗?

    ====================原创(同样破损)示例==================== ==

    state('home', {
                    url: "/home",
                    views: {
                        main: {templateUrl: "spage/home"},
                        actionmenu: {templateUrl:"spage/home/actionmenu"},
                        menu: {
                            templateProvider:
                                function ($http, $stateParams,  accessFactory) {
                                    //return '<md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button>';
                                    return accessFactory.getMenu('internal', function(menu){
                                        console.log("Got back " + menu);
                                        return menu;
                                        //return menu;
                                    });
    
                                    //return accessFactory.getMenu('internal');
                                }
                        }
                    }
    

    对于非异步调用,我可以使用return accessFactory.getMenu('internal')。我以为我可以使用Element,但这似乎已经死了。

    有什么建议吗?

    ============应该添加部分工厂================

       service.getMenu = function(req, callback){
    
    
            if (req === 'login'){
                callback('<md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Login" ui-sref="login"><md-icon md-svg-src="/images/icons-svg/unlock.svg" class="svg-icon" style="color: rgb(0, 0, 0);"></md-icon> </md-button>');
    
    //            return '<md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Login" ui-sref="login"><md-icon md-svg-src="/images/icons-svg/unlock.svg" class="svg-icon" style="color: rgb(0, 0, 0);"></md-icon> </md-button><md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button><md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button><md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button><md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button><md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button>';
            } else if(req === 'home'){
                callback('<md-button class="md-raised md-fab md-primary" md-theme="default" aria-label="Home" ui-sref="index"><md-icon md-svg-src="/images/icons-svg/home9.svg" class="svg-icon" style="color: rgb(255, 255, 255);"></md-icon> </md-button>');
            }
    

    根据文档(https://github.com/angular-ui/ui-router/wiki),它应该可以工作

    $stateProvider.state('contacts', {
      templateProvider: function ($timeout, $stateParams) {
        return $timeout(function () {
          return '<h1>' + $stateParams.contactId + '</h1>'
        }, 100);
      }
    })
    

    奇怪的是,超时版本的工作原理与回调给出的输出完全相同,我真的错过了一些真正明显的东西吗?

1 个答案:

答案 0 :(得分:2)

您是否尝试过返回$ promise。查看UI-Router wiki上使用的示例:

$stateProvider.state('contacts', {
  templateProvider: function ($timeout, $stateParams) {
    return $timeout(function () {
      return '<h1>' + $stateParams.contactId + '</h1>'
    }, 100);
  }
})

请注意以return $ timeout开头的行(....您是否尝试过accessFactory.getMenu('home')返回$ promise或使用$ q.defer()创建一个新的:

...
templateProvider:
      function ($q, $stateParams, accessFactory) {
          var deferred=$q.defer();
          accessFactory.getMenu('home',function(menu){
                 console.log("Got back " + menu);
                 deferred.resolve(menu);
                });
          return deferred.promise;
          }),
...