我目前正面临项目设计的问题。 我正在使用angularjs框架,我的任务是为网页提供翻译,但翻译需要从BE端的xml文件中提供。 因此,我发现在FE侧可以配置角度i18n,我不得不使用另一种策略。
我决定制作一个服务,在解决其他所有内容之前的解析期内获取数据:
app.factory('dictionaryService', ['$http', '$rootScope', function ($http, $rootScope) {
return {
getDictionary: function (defaultLanguage) {
var chosenLanguage = null;
if (angular.isUndefined($rootScope.defaultLanguage) || $rootScope.defaultLanguage == null) {
chosenLanguage = defaultLanguage;
$rootScope.defaultLanguage = chosenLanguage;
} else {
chosenLanguage = $rootScope.defaultLanguage;
}
var translation = new Array();
translation[chosenLanguage] = new Array();
return $http.get('Translation/GetCurrentDictionary/', {
params: {
language: chosenLanguage
}
});
},
GetLanguagesSetup: function () {
return $http.get('Translation/GetLanguagesSetup/');
}
}
}]);
然后按如下方式解决:
$routeProvider.when("/diagnose", {
controller: "diagnoseCtrl",
templateUrl: "/app/views/diagnose.html",
resolve: {
startupData: function (dictionaryService, $q) {
var def = $q.defer();
var translation = new Array();
var startupData = new Array();
var defaultLanguage = "EN";
var dict = dictionaryService.getDictionary(defaultLanguage).then(function (JSONData) {
var keys = Object.keys(JSONData.data.data);
var chosenLanguage = JSONData.data.lang;
translation[chosenLanguage] = {};
for (i = 0; i < keys.length; i++) {
translation[keys[i]] = JSONData.data.data[keys[i]];
}
startupData['translations'] = translation;
def.resolve(startupData);
}).catch(function (e) {
console.log("Translation fetching exception, " + e);
return $q.reject(e);
});
return def.promise;
}
}
});
因此,您可以看到我将获取的翻译存储在startupData中。然后在使用它的控制器中,我将此数据分配给$ rootScope。它似乎已经在这里作为一个不是最好的解决方案,但我无法想出一个不同的解决方案 然后我创建了一个翻译服务,获取直接翻译文本:
app.factory('translationService', ['$rootScope', '$http', function ($rootScope, $http) {
var translations = null;
return {
getText: function (key) {
if ($rootScope.cachedTranslations == undefined) {
return key;
}
var result = $rootScope.cachedTranslations[key];
if (result == null) {
return key;
} else {
return result;
}
}
}
}]);
这个解决方案的最大问题是,我没有使用promises,但我不想为每个翻译进行BE查询。 另一个问题是设计师提供的html模板:
<body ng-controller="mainController">
<loading-screen ng-show="!isDataLoaded"></loading-screen>
<div id="header" class="headerView" ng-controller="headerController" ng-show="isDataLoaded">
some header stuff
...
<button ng-bind="option1" ng-click="redirectTo('#subpage1')"></button>
<button ng-bind="option2" ng-click="redirectTo('#subpage2')"></button>
<button ng-bind="option3" ng-click="redirectTo('#subpage3')"></button>
<button ng-bind="language" ng-if="availableLanguages.length > 1" ng-repeat="language in availableLanguages" ng-click="setLanguage(language)"></button>
</div>
</div>
<
<div id="content" ng-view ng-show="isDataLoaded">
</div>
<footer id="footer" class="footer" ng-show="isDataLoaded">
<status-bar></status-bar>
</footer>
Resolve只适用于ng-views的控制器,但是标题内容也需要翻译,因此我需要在尝试应用翻译之前以某种方式使headerCtrl等待。 所以我做了另一个不受欢迎的决定,通过广播消息通知所有控制器关于完成的启动,并等到显示加载屏幕完成所有操作。 它看起来很好并且响应很快(此时每个启动1秒就可以接受)。
问题是,我发现这次尝试有很多设计错误,我无法想出更好的设计。
所以我的主要问题是: 如何让它变得更好?第一个服务返回第二个服务使用的整个数组,所以我不知道如何将它与promises结合使用? 我担心随着应用程序的发展,我会发现自己处于全局变量和全球事件地狱
提前感谢您的帮助!
答案 0 :(得分:1)
您似乎在寻找angular-translate的 angular-translate-loader-static-files 扩展程序。请参阅文档here。
这与$translateProvider
的正确配置一起将允许您从后端获取带有翻译的json文件,甚至可以根据需要交换翻译 - 例如用户更改语言设置,控制器重新配置$translateProvider
。您的工作已经完成 - 所有内容都将自动获取和更新,而无需重新加载页面。