我目前正在使用角度js编写一个前端应用程序。
我正在使用Restangular来处理所有REST请求。目前正在加载数据非常完美。
我想做以下事情:
我想编写一个服务/工厂/提供程序,它返回每种语言的名称。此调用只需要在整个工作流程中执行一次(当用户使用应用程序时,语言不太可能)。
所以我尝试过这样的事情:
'use strict';
angular.module('maroziFrontendApp')
.service('LanguagesService', function(Restangular) {
this.languages = Restangular.one('languages').get();
});
但是当我在我的控制器(或Restangular元素变换器)中注入它时,我只能得到承诺。然后,我必须做另一个回调,这会弄乱工作流程。
我也尝试过:
'use strict';
angular.module('maroziFrontendApp')
.service('LanguagesService', function(Restangular) {
Restangular.one('languages').get().then(function(languages) {
this.languages = languages;
});
});
但是这会在注入时返回undefined
。
澄清:
我希望在命中控制器(或elementtransformer)之前加载语言。我无法使用resolve
,因为我不仅在控制器中使用此服务。
有简单的方法吗?
答案 0 :(得分:3)
从版本1.2.0开始,您现在也可以在Restangular中使用$object
所以你的代码是:
angular.module('maroziFrontendApp')
.service('LanguagesService', function(Restangular) {
this.languages = Restangular.one('languages').get().$object;
});
然后在你的控制器中:
$scope.languages = LanguageService.languages
在HTML中:
<span>{{languages.name}}</span>
这看起来好多了:)
答案 1 :(得分:1)
在您的第二次尝试中,您在回调函数中引用了this
,这就是为什么我认为您正在获取undefined
。以下示例解决了该问题。
'use strict';
angular.module('maroziFrontendApp')
.service('LanguagesService', function(Restangular) {
var self = this;
Restangular.one('languages').get().then(function(languages) {
self.languages = languages;
});
});
这种方法仍然存在问题,因为需要使用LanguagesService的代码需要某种方式来了解它何时可用。
您可能需要考虑向用户显示某种“正在加载”的消息,然后使用module.run()
方法中的链式承诺加载所有必需的数据。加载所有数据后,您可以将用户重定向到应用程序入口点。
另一个需要考虑的选择是,如果应用程序的所有用户的语言列表都相同,请尝试生成并包含类似以下示例的javascript文件,您不必担心异步问题。
angular.module("maroziFrontendApp")
.value("Languages", function() {
return {
"en": "English",
"fr": "French",
"es": "Spanish"
};
});
答案 2 :(得分:1)
由于AJAX调用是异步的,因此无法确保在执行控制器函数之前加载语言。
对于它的价值,Restangular promises有一个名为$object
的属性。一旦返回响应,它就会被结果填充。
this.languages = Restangular.one('languages').get().$object;
答案 3 :(得分:0)
在/ loading之类的其他路线上加载数据,加载数据后,您可以重定向到您希望能够立即从服务中访问数据的页面。
答案 4 :(得分:0)
我可以想到一个非正统的解决方案,你手动引导角度应用程序。
首先启动服务,然后再启动。您必须删除当然的ng-app指令
var module = angular.module("app",['restangular','ngMockE2E']);
module.factory('LanguagesService', function(Restangular, $q) {
var service = {};
service.init = function() {
var defered = $q.defer();
Restangular.one('languages').get().then(function(languages) {
service.languages = languages;
service.init = undefined;
defered.resolve();
});
return defered.promise;
}
return service;
});
//Manual bootstrap
function bootstrap() {
var $injector = angular.injector(['app']);
$injector.invoke(function ($rootScope, $compile, $document, LanguagesService) {
LanguagesService.init().then(function() {
$compile($document)($rootScope);
});
});
}
bootstrap();
请参阅http://jsfiddle.net/VtazD/1/
缺点当然是初始加载时间,并且在应用程序完全加载之前会显示胡须,但我确定有解决方案。