使用多个控制器和一个服务处理角度承诺?

时间:2014-11-19 05:47:23

标签: javascript angularjs asynchronous angular-promise

我有一个名为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中提问,我是一名新开发人员,英语是我的第二语言。如果我的问题/描述有问题,请提前道歉。

2 个答案:

答案 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和示例,了解它是如何完成的。