我有一个简单的AngularJS应用程序。我现在正试图在其中实现L10n *机制。为此我有服务加载一个字符串文件并返回一个键值数组。这些值稍后会放入视图和控制器中。
为了保持简单和简单,我将返回数组分配给 $ rootScope ,以便每个控制器/视图都可以访问同一个列表。 我是从 angular.module(...)。run()函数
中完成的。这就是问题开始的地方 - 一些控制器可以访问$ rootScope对象,而另一些控制器则无法访问(并返回undefined)。我怀疑这是因为在加载前几个控制器之前,承诺没有得到及时解决。
问题是 - 如何让控制器等待加载资源?
辅助问题 - GenericListController 为什么可以使用$ scope.localisation但 ListController 不能?
服务声明
app.factory("StringsTranslationService", function($http) {
var getData = function(locale) {
return $http({method:"GET", url:'public/resources/strings_'+locale+'.txt'}).then(function(result){
return result.data[0];
});
};
return { getData: getData };
});
在 app.js
中将服务中的数据加载到$ rootScopeapp.run(function($rootScope,StringsTranslationService) {
var myDataPromise = StringsTranslationService.getData('en');
myDataPromise.then(function(result) {
$rootScope.localisation=result;
});
});
最后尝试在 controller.js :
中使用var app=angular.module('myApp');
app.controller('ListController', function ($scope, $controller){
console.log($scope.localisation["_NAME_"]);
angular.extend(this, $controller('GenericListController', {$scope: $scope}));
});
最有趣的事实是 GenericListController 也使用相同的$ scope.localisation数组,它没有问题!
加载顺序为:
答案 0 :(得分:1)
不应将yr结果复制到$ rootScope,而应直接从服务中读取。
为什么? Yr $ rootScope在整个应用程序生命周期中存在,它位于所有控制器的范围之上,因此最好保持最轻。
代码:
app.factory("StringsTranslationService", function($http,$q) {
var StringsTranslationService={};
var data='';
var dataReady=false;
StringsTranslationService.getData = function (locale) {
var deferred= $q.defer();
$http({
method:"GET",
url:'public/resources/strings_'+locale+'.txt'
})
.success(function(result){
deferred.resolve(result.data[0]);
})
.error(function(error){
deferred.reject(error);
})
return deferred.promise;
};
return StringsTranslationService;
});
更新你的app.run
app.run(function(StringsTranslationService){
//call service & read data
StringsTranslationService.getData('en')
.then(function(data){
StringsTranslationService.data=data;
StringsTranslationService.dataReady=true;
//if you really want it add to rootScope
//$rootScope.localisation=data;
},
function(error){
//handle error here
})
});
内部控制器检查数据是否准备好&然后阅读
app.controller('ListController', function ($scope, StringsTranslationService){
if(StringsTranslationService.dataReady===false){
$scope.loading=true;
}
else {
$scope.loading=false;
$scope.data=StringsTranslationService.data;
}
});
通过这种方式,您只需拨打一次电话即可获取数据&它将在应用程序中提供。