角UI路由器:解决从URL状态 [英] ANGULAR-UI-ROUTER: Resolve state from URL
问题描述
我正在与动力状态的应用程序,有时我需要从URL解析国家名称。
例如:我有 /仪表板/用户/ 12268
,我需要得到国家'dashboard.user
。
有什么办法由给出的工具UI路由器
来做到这一点?我无法找出如何做这方面的权利...
我在做动态加载模块与requireJS的应用程序。在第一时间,因为用户被发送到登录状态是没有问题的。登录后,我用只需要加载的用户可以访问的状态。但是,当用户重新加载页面,我再次加载模块,并且需要将URL解析到一个状态,还有就是问题所在。我已经开始与urlMatcherFactory努力,但解决不了他们。
的状态的URL解析后装入。
该流程(页面刷新后的http://本地主机:8090 / index.html的#/仪表板/用户/ 12268
)
- 引导应用程序(不包括美国)
- 在这一点上,<code> UI路由器已加载
- 获取用户有权访问该国,并注册它们(这些国家被注册的在配置相)
- 找到了,如果我有一个给定的URL重定向到有相匹配的状态。这就是我卡住了。
要加载的应用程序后,引导状态,我用的<一个变化href=\"http://www.bennadel.com/blog/2554-loading-angularjs-components-with-requirejs-after-application-bootstrap.htm\"相对=nofollow>本纳德尔的解决方案,包括国家和常量。
我的数据主
在RequireJS有这个初始化code:
require.config({\r
// REQUIREJS配置\r
});\r
\r
需要(['应用'],功能(应用程序){\r
app.bootstrap(文件);\r
\r
VAR纳克= angular.injector(['NG']);\r
变量$ =窗口ng.get('$窗口)\r
变量$ Q = ng.get('$ Q');\r
\r
VAR appStorage = $ window.localStorage;\r
VAR loadedManifests;\r
\r
尝试{\r
loadedManifests = JSON.parse(appStorage.getItem('loadedManifests'));\r
}赶上(E){\r
loadedManifests = [];\r
}\r
\r
如果(!angular.isArray(loadedManifests)|| loadedManifests.length === 0){\r
$ q.all([\r
app.loadManifest(登录/清单),// loadMainfest函数加载状态进行登录\r
app.loadManifest('注销/清单)//负载注销状态\r
])\r
。然后(函数(){\r
app.injector.get('$ rootScope')。$ evalAsync(函数(){\r
。app.injector.get('$状态')去('密码');\r
});\r
});\r
}其他{\r
变种promisesArray = [];\r
\r
对于(VAR I = 0; loadedManifests [I];我++){\r
promisesArray.push(app.loadManifest(loadedManifests [I])); //加载在localStorage的所有已注册的体现\r
}\r
\r
$ q.all(promisesArray)。然后(函数(){\r
// TODO:卡住。从查询字符串获取URL和解决有效状态,或重定向到/登录\r
});\r
}\r
});
\r
的 loadManifest
功能寄存器毕竟,引导我的应用程序内容(服务,工厂,控制器,路由器,...)。
感谢您的帮助,
ALX
的https: //github.com/angular-ui/ui-router/issues/1651
您可以使用 .decorator
勾上 $ stateProvider
暴露出内部状态的实现。您可以装点国家建设者的任何财产;我选择了父随意。
的app.config(函数($ stateProvider){
$ stateProvider.decorator(父,功能(internalStateObj,parentFn){
//这个FN由StateBuilder每一个国家被注册时被调用 //第一个arg是内部状态。捕捉它,并添加一个访问公共状态的对象。
。internalStateObj.self $$状态=函数(){返回internalStateObj; }; //通过默认.parent()函数
返回parentFn(internalStateObj);
});
});
现在您可以通过访问内部状态对象。$$状态()
,例如
VAR publicState = $ state.get(富);
VAR privateInternalState = publicState $$状态()。
二,循环遍历$ state.get(每个州),并测试他们对你的URL片段。
angular.forEach($ state.get()函数(州){
VAR privatePortion =状态$$状态()。
VAR匹配= privatePortion.url.exec(URL,queryParams);
如果(匹配)的console.log(匹配的状态:+ state.name +和参数:+匹配);
});
I'm making an app with dynamical states, and sometimes I need to resolve the state name from the url.
e.g.: I have /dashboard/user/12268
and I need to get the state 'dashboard.user'
.
Is there any way to do this with the tools given by ui-router
? I can't find out how to do this right now...
I'm making an app with dynamic module loading with requireJS. At first time there is no problem because user is sent to login state. After login, I use require to load only the states the user has access to. But when the user reloads the page, I load the modules again, and need to resolve the url to a state, and there's the problem. I've started trying with urlMatcherFactory but can't resolve them.
The state is loaded after the URL resolution.
The flow is (after the refresh of page http://localhost:8090/index.html#/dashboard/user/12268
):
- bootstrap the app (without states)
- at this point,
ui-router
has been loaded - get the states the user has access to, and register them (these states are registered after config phase)
- find out if i have a state that matches the given url to redirect to there. This is where I'm stuck.
To load states after application bootstrap, I've used a variation of Ben Nadel's solution that includes states and constants.
My data-main
in RequireJS has this initialization code:
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
});
}
});
TheloadManifest
function registers all after-bootstrap elements on my app (services, factories, controllers, routers, ...).
Thanks for your help,
Alx
https://github.com/angular-ui/ui-router/issues/1651
You can expose the internal state implementation by using the .decorator
hook on $stateProvider
. You can decorate any property of the state builder; I chose 'parent' arbitrarily.
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);
});
});
Now you can access the internal state object using .$$state()
, e.g.
var publicState = $state.get("foo");
var privateInternalState = publicState.$$state();
Second, loop over each state in $state.get() and test them against your URL fragment.
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路由器:解决从URL状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!