我有一个名为mainService的工厂,它包含将用于填充自身的ajax函数。在mainController中调用此函数以填充mainService。现在,我在另一个控制器中使用了mainService,有时数据尚未可用,因为承诺尚未得到解决。处理这个问题的最佳方法是什么?以下是一些代码:
function MainService(http, $q) {
//var deffered = $q.defer();
var svc = {
userLoggedIn: false,
userInfo: {},
settings: {},
loadingCount:0,
getSettings: function () {
var deferred = $q.defer();
http.get(rootUrl + 'api/settings').success(function (data) {
svc.settings = data;
deferred.resolve(data);
});
return deferred.promise;
}
return svc;
MainController中的:
mainservice.getSettings().then(function(data){
//stuffs
});
:
$scope.settings = mainservice.settings.usersettings;
另一个控制器正在处理某些UI,因此只有在用户点击某些内容时才会运行。有时,如果用户过早点击错误,则无法读取未定义的属性用户设置'之后,有时用户再次点击时会出现错误,有时会在用户再次点击后运行,为什么会这样?
我可以在OtherController中再次执行mainservice.getSettings()。then(),但这并不是正确的方法。任何帮助将不胜感激。
nb:这是我第一次在stackoverflow中提问,我是一名新开发人员,英语是我的第二语言。如果我的问题/描述有问题,请提前道歉。
答案 0 :(得分:0)
您应该禁用UI控件,直到用户最终可以在UI中执行某些操作,或者在数据可用之前隐藏UI。我认为两者都可以。 例如,您可以使用ng-disabled =" dataAvailable"禁用该按钮。并在getSettings()。than(function(){dataAvaialble = true})中启用它。 隐藏你可以使用ng-show或ng-class,并再次根据你的范围的模态状态。
getSettings可能存在的问题是你每次都会在那里激活一个get调用,我猜你想在整个应用程序中执行一次。 所以数据应该缓存在MainService中,所以第二次你应该返回第一次调用的promise。
答案 1 :(得分:0)
此行为的原因是您的服务调用的异步性质。假设OtherController
是嵌套控制器并与MainController
共享范围。您可以使用手表检查数据何时可供OtherController
使用:
$scope.$watch('settings',function(newValue) {
if(newValue) $scope.settings = newValue.usersettings;
});
使用.getSettings().then()
也没问题,但每次发出新请求时都应该缓存远程响应。
另一种选择是使用$routeProvider
resolve
配置将此数据传递给MainController
。在这种情况下,只有在设置数据可用时才会加载MainController。查看resolve
documentation和示例,了解它是如何完成的。