我正在构建一个将在多个域上运行的角度应用程序。由于每个域上有不同的配置,因此我需要通过调用服务器来获取所有变量。该调用将返回包含不同rest url的JSON对象。 我的问题是我需要在“解决问题”之前做这个电话。步入$ stateProvider,因为我已经有一个依赖于服务器配置对象的任务。
答案 0 :(得分:3)
这里应该做的是一个非常棒的功能 $urlRouterProvider.deferIntercept();
:
deferIntercept(defer)
禁用(或启用)延迟位置更改拦截。
如果您希望自定义同步URL 的行为(例如,如果您希望延迟转换但保留当前URL),请在配置时调用此方法。然后,在运行时,在配置自己的
$urlRouter.listen()
事件处理程序后调用$locationChangeSuccess
。
API文档中的代码段:
var app = angular.module('app', ['ui.router.router']);
app.config(function($urlRouterProvider) {
// Prevent $urlRouter from automatically intercepting URL changes;
// this allows you to configure custom behavior in between
// location changes and route synchronization:
$urlRouterProvider.deferIntercept();
}).run(function($rootScope, $urlRouter, UserService) {
$rootScope.$on('$locationChangeSuccess', function(e) {
// UserService is an example service for managing user state
if (UserService.isLoggedIn()) return;
// Prevent $urlRouter's default handler from firing
e.preventDefault();
UserService.handleLogin().then(function() {
// Once the user has logged in, sync the current URL
// to the router:
$urlRouter.sync();
});
});
// Configures $urlRouter's listener *after* your custom listener
$urlRouter.listen();
});
而且,与此问题相关:
为了清楚说明,适合这个用例,让我们观察plunker的代码。
因此,首先我们可以看到 .config()
阶段。它确实可以访问提供商,但不能访问其服务(例如$http
)。还没有,服务本身将在以后提供......
app.config(function ($locationProvider, $urlRouterProvider, $stateProvider)
{
// this will put UI-Router into hibernation
// waiting for explicit resurrection later
// it will give us time to do anything we want... even in .run() phase
$urlRouterProvider.deferIntercept();
$urlRouterProvider.otherwise('/other');
$locationProvider.html5Mode({enabled: false});
$stateProviderRef = $stateProvider;
});
我们所做的是设置对提供者(可配置对象)的引用,稍后将使用:$stateProviderRef
。
最重要的是我们停止了UI-Router,并迫使他用 $urlRouterProvider.deferIntercept();
等我们(请参阅doc并在上面引用)
.run()
阶段的摘录:
app.run(['$q', '$rootScope','$http', '$urlRouter',
function ($q, $rootScope, $http, $urlRouter)
{
// RUN phase can use services (conigured in config phase)
// e.g. $http to load some data
$http
.get("myJson.json")
.success(function(data)
{
// here we can use the loaded stuff to enhance our states
angular.forEach(data, function (value, key)
{
var state = { ... }
...
$stateProviderRef.state(value.name, state);
});
// Configures $urlRouter's listener *after* your custom listener
// here comes resurrection of the UI-Router
// these two important calls, will return the execution to the
// routing provider
// and let the application to use just loaded stuff
$urlRouter.sync();
$urlRouter.listen();
});
}]);
最重要的是,此.run()
仅执行 ONCE 。只有一次。我们要求。
我们还可以使用另一种技术:解析一个超级根状态的内部,这是所有状态层次结构根的父级。检查所有详细信息:
Nested states or views for layout with leftbar in ui-router?
答案 1 :(得分:0)
还有另一种解决方法:
如何在
$http
内执行resolve
属性之前解决$stateProvider
请求?
如果我们只需要在 $http
中获得一些resolve
结果,我们就可以这样做:
resolve: {
myResolve1:
function($http, $stateParams) {
return $http.get("/api/foos/"+stateParams.fooID);
}
}
这是[$stateProvider][1]
部分resolve
的文档摘录。我们可以看到,我们返回$ http服务的承诺:return $http.get()
所以,要扩展到asnwer:
但是如何让ui-router等到承诺得到解决?
我们可以使用return $http.get()
然后使用.then()
。在其中,我们可以访问返回的结果 - 我们可以调整:
myResolve1:
function($http, $stateParams) {
// we still return the promise of the $http.get))
return $http
.get("/api/foos/"+stateParams.fooID)
.then(function(response) {
// but now, the content of resolved property
// will be the first item of the loaded array
return response.data[0];
};
}
}
还有一种解决方案 - 如果我们需要在每个州之前实现这一点。我们只是介绍一些“根”状态作为超级父母。它将包含这样的解决方案,并且所有子状态将等到这个解决后,但只解决了一次。点击此处:angular ui-router resolve for parent state