我正在构建一个将在多个域上运行的 Angular 应用程序。由于每个域都有不同的配置,我需要通过调用服务器来获取所有变量。该调用将返回一个包含不同 rest url 的 JSON 对象。
我的问题是我需要在 $stateProvider 中的“解决”步骤之前执行此调用,因为我已经有一个依赖于服务器配置对象的任务。
最佳答案
在这里应该起作用的是一个非常棒的功能 $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();
});
而且,与这个问题有关:有working example - plunker
为了说清楚,适合这个用例,让我们观察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()
刚刚被处决 一次 .只有一次。按照我们的要求。我们还可以使用另一种技术:在一个 super 根状态内部解析,它是所有状态层次结构根的父级。在此处检查所有详细信息:
Nested states or views for layout with leftbar in ui-router?
关于angularjs - 需要在 $stateProvider 内部的 resolve 属性执行之前解析 $http 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29181503/