2015-04-27 82 views
8

我正在製作具有動態狀態的應用程序,有時我需要從url解析狀態名稱。ANGULAR-UI-ROUTER:從URL解析狀態

例如:我有/dashboard/user/12268,我需要得到狀態'dashboard.user'

有什麼辦法可以用ui-router給出的工具做到這一點?我現在無法知道如何執行此操作...

我正在使用requireJS加載動態模塊加載的應用程序。第一次沒有問題,因爲用戶被髮送到登錄狀態。登錄後,我使用require只加載用戶有權訪問的狀態。但是,當用戶重新加載頁面時,我再次加載模塊,並需要將url解析爲狀態,並且存在問題。我已經開始嘗試使用urlMatcherFactory,但無法解決它們。

狀態在URL解析後加載。

的流動(http://localhost:8090/index.html#/dashboard/user/12268頁面刷新後):

  • 引導應用程序(不包括美國)
  • 在這一點上,ui-router已加載
  • 獲得用戶訪問狀態並註冊它們(這些狀態在配置階段後註冊
  • 找出我是否有一個狀態匹配給定的URL重定向到那裏。這是我卡住的地方。

要在應用程序引導後加載狀態,我使用了包含狀態和常量的Ben Nadel's solution的變體。

data-main在RequireJS有這樣的初始化代碼:

require.config({ 
 
    // REQUIREJS CONFIGURATION 
 
}); 
 

 
require(['app'], function (app) { 
 
    app.bootstrap(document); 
 

 
    var ng = angular.injector(['ng']); 
 
    var $window = ng.get('$window') 
 
    var $q = ng.get('$q'); 
 

 
    var appStorage = $window.localStorage; 
 
    var loadedManifests; 
 

 
    try { 
 
     loadedManifests = JSON.parse(appStorage.getItem('loadedManifests')); 
 
    } catch(e) { 
 
     loadedManifests = []; 
 
    } 
 

 
    if (!angular.isArray(loadedManifests) || loadedManifests.length === 0) { 
 
     $q.all([ 
 
       app.loadManifest('login/manifest'), //loadMainfest function loads the states for login 
 
       app.loadManifest('logout/manifest') //load states for logout 
 
      ]) 
 
      .then(function() { 
 
       app.injector.get('$rootScope').$evalAsync(function() { 
 
        app.injector.get('$state').go('login'); 
 
       }); 
 
      }); 
 
    } else { 
 
     var promisesArray = []; 
 

 
     for(var i = 0; loadedManifests[i]; i++) { 
 
      promisesArray.push(app.loadManifest(loadedManifests[i])); //load all manifests registered on localstorage 
 
     } 
 

 
     $q.all(promisesArray).then(function(){ 
 
      //TODO: Stuck. Get URL from querystring and resolve to valid state, or redirect to /login 
 
     }); 
 
    } 
 
});

loadManifest函數註冊後,所有的自舉我的應用程序元素(服務,工廠,控制器,路由器,... )。

感謝您的幫助,
ALX

+2

請發佈到目前爲止 – tim

+0

我正在使用requireJS加載動態模塊加載的應用程序。第一次沒有問題,因爲用戶被髮送到登錄狀態。登錄後,我使用require只加載用戶有權訪問的狀態。 但是當用戶重新加載頁面,我再次加載模塊,並且需要將URL解析到一個狀態,還有就是問題所在。我已經開始與urlMatcherFactory嘗試但不能解決他們 的URL解析後的狀態加載 –

+0

UI-路由器額外未來狀態可以管理您的情況爲您提供:http://christopherthielen.github.io/ui-router -extras /#/未來 –

回答

1

最後,我必須做出對UI的路由器$state服務一個小的修改去解決。

其結果是存儲在服務中的狀態具有更多的信息,即在$state.get()方法上給出的信息。所以我遍歷他們得到與我的URL匹配的狀態:

/** 
 
* @ngdoc function 
 
* @name ui.router.state.$state#fromUrl 
 
* @methodOf ui.router.state.$state 
 
* 
 
* @description 
 
* A method to resolve a state and its parameters from a given URL 
 
* 
 
* @returns {boolean} Returns a state that matches with the given URL, or undefined if no match 
 
*/ 
 
$state.fromUrl = function(url) { 
 
    if(!angular.isString(url)) { 
 
    //Only valid strings allowed 
 
    return undefined; 
 
    } 
 
    
 
    
 
    var keys = objectKeys(states); 
 
    //Iterate over all states 
 
    for(var i = 0; i < keys.length; i++) { 
 
    var state = states[keys[i]]; 
 
    var stateArgs = state.url.exec(url); 
 

 
    //If the state's URL does not match then stateArgs will be false 
 
    if(!!stateArgs) { 
 
     return { 
 
     name: state.name, 
 
     args: stateArgs 
 
     } 
 
    } 
 
    } 
 

 
    return undefined; 
 
};

問候

+0

哪裏「指出:」來自於objectKeys(州)? –

14

https://github.com/angular-ui/ui-router/issues/1651


ALX

可以公開的內部狀態的實現使用$stateProvider上的.decorator掛鉤。你可以裝飾國家建設者的任何財產;我任意選擇了「父母」。


app.config(function($stateProvider) { 
    $stateProvider.decorator('parent', function (internalStateObj, parentFn) { 
    // This fn is called by StateBuilder each time a state is registered 

    // The first arg is the internal state. Capture it and add an accessor to public state object. 
    internalStateObj.self.$$state = function() { return internalStateObj; }; 

    // pass through to default .parent() function 
    return parentFn(internalStateObj); 
    }); 
}); 

現在您可以訪問使用.$$state()內部狀態的對象,例如

var publicState = $state.get("foo"); 
var privateInternalState = publicState.$$state(); 

其次,循環遍歷$ state.get()每一個州和測試他們對你的網址片段。

angular.forEach($state.get(), function(state) { 
    var privatePortion = state.$$state(); 
    var match = privatePortion.url.exec(url, queryParams); 
    if (match) console.log("Matched state: " + state.name + " and parameters: " + match); 
}); 
+0

這是一個很好的設計證明。可擴展性... –

+0

最好。解。永遠。 謝謝! –

+3

在搜索部分,加入'如果回報(州$$狀態!);'將是一件好事,因爲我這沒那財產_global_抽象的狀態,並導致了錯誤。 – Parziphal

0

要獲得@克里斯T溶液爲我工作我做這個服務裏面:

app.service('Helper', ['$state', '$location', 
    function($state, $location){ 

     var services = {}; 

     services.stateIs = function(state_name){ 
      var current_path = $location.$$path; 
      var state = $state.get(state_name); 

      if(state){ 
       var state_regexp = state.$$state().url.regexp; 
       return state_regexp.test(current_path); 
      }else{ 
       return false; 
      } 
     } 

     return services; 
    } 
]); 

所以後來我可以在任何地方注入助手,做這樣的:

if(Helper.stateIs('app.user')){ 
    //yeah 
}