AngularJS UI路由器:如何解决全球范围内的典型数据为所有路线? [英] AngularJS ui-router: how to resolve typical data globally for all routes?
问题描述
我有一个与服务器返回的通信服务AngularJS
应用程序的不同部分的翻译
角
.module('utils的')
。服务('翻译',['$ Q,$ HTTP',函数($ Q $ HTTP){
translationsService = {
得到:函数(部分){
如果(!诺){
变种Q = $ q.defer();
答应= $ HTTP
。得到(
'/ API /翻译,
{
部分:部分
})
.success(功能(数据,状态,头,配置){
q.resolve(result.data);
})
.error(功能(数据,状态,头,配置){
q.reject(状态);
});
返回q.promise;
}
}
}; 返回translationsService;
}]);
节的名称为部分通过
的 GET
函数的参数。
我使用AngularJS UI路由器模块和下面的设计模式描述 href=\"https://scotch.io/tutorials/making-skinny-angularjs-controllers\">
所以,我有以下状态配置:
angular.module(应用)
的.config(['$ stateProvider',函数($ stateProvider){
$ stateProvider
.STATE('用户',{
网址:'/用户,
解析:{
翻译:'翻译',
功能(翻译){
返回Translations.get(用户);
}
]
},
templateUrl:/app/users/list.html',
控制器:'usersController',
controllerAs:虚拟机
})
.STATE('转移',{
网址:'/班',
解析:{
翻译:'翻译',
功能(翻译){
返回Translations.get('轮班');
}
]
},
templateUrl:/app/shifts/list.html',
控制器:'shiftsController',
controllerAs:虚拟机
})
这工作正常,但你可能会注意到我必须明确指定的决心参数翻译
。我认为这是不够好,因为这重复的逻辑。
有什么办法来解决全球的翻译和避免code重复。我的意思是某种中间件。
我在想监听的 $ stateChangeStart
,然后得到具体到新的状态转换,并将其绑定到控制器,但我还没有发现这样做的方式
任何意见,将大大pciated AP $ P $。
重要注意事项:
在我的情况下解决翻译对象
必须包含翻译数据,而不是服务/工厂/不管。
亲切的问候。
虽然这是一个很老的问题,我想发布我现在使用哪种解决方案。希望这将帮助别人的未来。
使用一些不同的方法后,我想出了href=\"https://github.com/johnpapa/angular-styleguide#routing\"由约翰·帕帕
他建议使用一个特殊的服务 routerHelperProvider
和配置状态作为一个普通JS对象。我不会给整个提供商在这里复制粘贴。参见上面的内容的链接。但我要告诉我如何通过服务的方式解决了我的问题。
下面是提供这需要的JS对象,并将其转变为各州配置code部分:
函数configureStates(州,otherwisePath){
states.forEach(函数(州){
$ stateProvider.state(state.state,state.config);
});
我把它改造如下:
函数configureStates(州,otherwisePath){ states.forEach(函数(州){ VAR resolveAlways = { 翻译:'翻译',函数(翻译){ 如果(state.translationCategory){ 返回Translations.get(state.translationCategory); }其他{ 返回{}; } }], }; state.config.resolve = angular.extend(state.config.resolve || {},resolveAlways || {}); $ stateProvider.state(state.state,state.config); });});
和我的路由配置的对象现在看起来如下:
{
状态:'用户',
translationsCategory:'用户',
配置:{
控制器:'usersController
controllerAs:虚拟机,
网址:'/用户。
templateUrl:users.html
}
所以,我所做的:
我实现了 resolveAlways
对象这需要自定义 translationsCategory
属性,注入了翻译
服务和解决必要的数据。现在没有必要去做每次。
I have an AngularJS service which communicates with the server and returns translations of different sections of the application:
angular
.module('utils')
.service('Translations', ['$q','$http',function($q, $http) {
translationsService = {
get: function(section) {
if (!promise) {
var q = $q.defer();
promise = $http
.get(
'/api/translations',
{
section: section
})
.success(function(data,status,headers,config) {
q.resolve(result.data);
})
.error(function(data,status,headers,config){
q.reject(status);
});
return q.promise;
}
}
};
return translationsService;
}]);
The name of the section is passed as the section
parameter of the get
function.
I'm using AngularJS ui-router module and following design pattern described here
So I have the following states config:
angular.module('app')
.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('users', {
url: '/users',
resolve: {
translations: ['Translations',
function(Translations) {
return Translations.get('users');
}
]
},
templateUrl: '/app/users/list.html',
controller: 'usersController',
controllerAs: 'vm'
})
.state('shifts', {
url: '/shifts',
resolve: {
translations: ['Translations',
function(Translations) {
return Translations.get('shifts');
}
]
},
templateUrl: '/app/shifts/list.html',
controller: 'shiftsController',
controllerAs: 'vm'
})
This works fine but as you may notice I have to explicitly specify translations
in the resolve parameter. I think that's not good enough as this duplicates the logic.
Is there any way to resolve translations globally and avoid the code duplicates. I mean some kind of middleware.
I was thinking about listening for the $stateChangeStart
, then get translations specific to the new state and bind them to controllers, but I have not found the way to do it.
Any advice will be appreciated greatly.
Important note:
In my case the resolved translations object
must contain the translations data, not service/factory/whatever.
Kind regards.
Though this is a very old question, I'd like to post solution which I'm using now. Hope it will help somebody in the future. After using some different approaches I came up with a beautiful angularjs pattern by John Papa
He suggest using a special service routerHelperProvider
and configure states as a regular JS object. I'm not going to copy-paste the entire provider here. See the link above for details. But I'm going to show how I solved my problem by the means of that service.
Here is the part of code of that provider which takes the JS object and transforms it to the states configuration:
function configureStates(states, otherwisePath) {
states.forEach(function(state) {
$stateProvider.state(state.state, state.config);
});
I transformed it as follows:
function configureStates(states, otherwisePath) {
states.forEach(function(state) {
var resolveAlways = {
translations: ['Translations', function(Translations) {
if (state.translationCategory) {
return Translations.get(state.translationCategory);
} else {
return {};
}
}],
};
state.config.resolve =
angular.extend(state.config.resolve || {}, resolveAlways || {});
$stateProvider.state(state.state, state.config);
});
});
And my route configuration object now looks as follows:
{
state: ‘users’,
translationsCategory: ‘users’,
config: {
controller: ‘usersController’
controllerAs: ‘vm’,
url: ‘/users’.
templateUrl: ‘users.html'
}
So what I did:
I implemented the resolveAlways
object which takes the custom translationsCategory
property, injects the Translations
service and resolves the necessary data. Now no need to do it everytime.
这篇关于AngularJS UI路由器:如何解决全球范围内的典型数据为所有路线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!