$stateProvider 里面的 resolve 属性 执行之前需要解析一个 $http 请求
Need to resolve a $http request before the execution of the resolve property inside $stateProvider
我正在构建一个 angular 应用程序,它将在多个域上 运行。由于每个域都有不同的配置,我需要通过调用服务器来获取所有变量。该调用将 return 一个包含不同 rest url 的 JSON 对象。
我的问题是我需要在 $stateProvider 中的 'resolve' 步骤之前执行此调用,因为我已经有一个任务依赖于来自服务器的配置对象。
这里应该工作的是一个非常棒的功能 $urlRouterProvider.deferIntercept();
记录在这里:
$urlRouterProvider
The deferIntercept(defer)
Disables (or enables) deferring location change interception.
If you wish to customize the behavior of syncing the URL (for example, if you wish to defer a transition but maintain the current URL), call this method at configuration time. Then, at run time, call $urlRouter.listen()
after you have configured your own $locationChangeSuccess
event handler.
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();
});
另外,与这个问题相关:
- AngularJS - UI-router - How to configure dynamic views
为了说清楚,适合这个用例,让我们观察一下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。只有一次。正如我们所要求的。
我们还可以使用另一种技术:在一个超级根状态内部解析,它是所有状态层次结构根的父级。在此处查看所有详细信息:
还有另一种方法可以解决:
How to resolve $http
request before the execution of the resolve
property inside $stateProvider
?
如果我们只需要在 resolve
中得到一些 $http
结果,我们可以这样做:
resolve: {
myResolve1:
function($http, $stateParams) {
return $http.get("/api/foos/"+stateParams.fooID);
}
}
这是 [$stateProvider][1]
部分 resolve
的文档片段。我们可以看到,我们 return $http 服务的承诺:return $http.get()
因此,将其扩展为答案:
But how can I make the ui-router wait until the promise is resolved?
我们可以只使用 return $http.get()
然后 .then()
。在其中,我们可以访问 returned 结果——我们可以对其进行调整:
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];
};
}
}
还有增强型解决方案 - 以防我们需要在每个状态之前实现这一点。我们只是引入一些 "root" 状态作为超级父级。它将包含这样的解决,所有子状态将等到这个解决,但只解决一次。在此处查看更多信息:angular ui-router resolve for parent state
我正在构建一个 angular 应用程序,它将在多个域上 运行。由于每个域都有不同的配置,我需要通过调用服务器来获取所有变量。该调用将 return 一个包含不同 rest url 的 JSON 对象。 我的问题是我需要在 $stateProvider 中的 'resolve' 步骤之前执行此调用,因为我已经有一个任务依赖于来自服务器的配置对象。
这里应该工作的是一个非常棒的功能 $urlRouterProvider.deferIntercept();
记录在这里:
$urlRouterProvider
The
deferIntercept(defer)
Disables (or enables) deferring location change interception.
If you wish to customize the behavior of syncing the URL (for example, if you wish to defer a transition but maintain the current URL), call this method at configuration time. Then, at run time, call
$urlRouter.listen()
after you have configured your own$locationChangeSuccess
event handler.
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();
});
另外,与这个问题相关:
- AngularJS - UI-router - How to configure dynamic views
为了说清楚,适合这个用例,让我们观察一下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。只有一次。正如我们所要求的。
我们还可以使用另一种技术:在一个超级根状态内部解析,它是所有状态层次结构根的父级。在此处查看所有详细信息:
还有另一种方法可以解决:
How to resolve
$http
request before the execution of theresolve
property inside$stateProvider
?
如果我们只需要在 resolve
中得到一些 $http
结果,我们可以这样做:
resolve: {
myResolve1:
function($http, $stateParams) {
return $http.get("/api/foos/"+stateParams.fooID);
}
}
这是 [$stateProvider][1]
部分 resolve
的文档片段。我们可以看到,我们 return $http 服务的承诺:return $http.get()
因此,将其扩展为答案:
But how can I make the ui-router wait until the promise is resolved?
我们可以只使用 return $http.get()
然后 .then()
。在其中,我们可以访问 returned 结果——我们可以对其进行调整:
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];
};
}
}
还有增强型解决方案 - 以防我们需要在每个状态之前实现这一点。我们只是引入一些 "root" 状态作为超级父级。它将包含这样的解决,所有子状态将等到这个解决,但只解决一次。在此处查看更多信息:angular ui-router resolve for parent state