簡體   English   中英

ANGULAR-UI-ROUTER:從URL解析狀態

[英]ANGULAR-UI-ROUTER: Resolve state from URL

我正在創建一個具有動態狀態的應用程序,有時我需要從URL解析狀態名稱。

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

ui-router提供的工具有沒有辦法做到這一點? 我現在無法知道如何做到這一點......

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

在URL解析后加載狀態。

該流程是(在刷新頁面http://localhost:8090/index.html#/dashboard/user/12268 ):

  • 引導應用程序(沒有狀態)
  • 此時, ui-router已經加載
  • 獲取用戶有權訪問的狀態,並注冊它們(這些狀態配置階段注冊)
  • 找出我是否有一個匹配給定網址的狀態重定向到那里。 這就是我被困住的地方。

為了在應用程序引導之后加載狀態,我使用了Ben Nadel解決方案的變體,其中包括狀態和常量。

我在RequireJS中的data-main有這個初始化代碼:

 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

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

您可以使用$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()中的每個狀態,並針對您的URL片段測試它們。

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

最后,我不得不對ui-router的$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; }; 

問候,
ALX

要讓@Chris 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;
    }
]);

所以后來我可以在任何地方注入Helper並執行此操作:

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

當前狀態可以從$ state service獲得。 $state.current檢查這個api http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM