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

Javascript 使用多个控制器和一个服务处理角度承诺?,javascript,angularjs,asynchronous,angular-promise,Javascript,Angularjs,Asynchronous,Angular Promise,我有一个名为mainService的工厂,它由用于填充自身的ajax函数组成。在mainController中调用此函数以填充mainService。现在,我在另一个控制器中使用mainService,有时数据还不可用,因为承诺还没有解决。处理这个问题的最好方法是什么?以下是一些代码: function MainService(http, $q) { //var deffered = $q.defer(); var svc = { userLoggedIn: false, u

我有一个名为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;
在主控制器中:

mainservice.getSettings().then(function(data){
     //stuffs
});
$scope.settings = mainservice.settings.usersettings;
在其他控制器中:

mainservice.getSettings().then(function(data){
     //stuffs
});
$scope.settings = mainservice.settings.usersettings;
另一个控制器正在处理某个UI,因此它仅在用户单击某个对象时运行。有时,如果用户过早单击,则会出现错误“无法读取未定义的属性usersettings”。之后,有时,当用户再次单击时,该错误会持续存在,有时,该错误会在用户再次单击后运行,这是为什么

我可以执行mainservice.getSettings。然后再次在OtherController中执行,但这不是正确的方式。任何帮助都将不胜感激


注:这是我第一次在stackoverflow中提问,我是一名新开发人员,英语是我的第二语言。如果我的问题/描述有问题,请提前道歉。

您应该禁用UI控件,直到用户最终可以在UI中执行某些操作,或者在数据可用之前隐藏UI。我想两者都可以。 例如,您可以使用ng disabled=dataAvailable禁用按钮,并在getSettings.than函数{dataAvailable=true}中启用该按钮。 隐藏可以使用ng show或ng类进行,也可以根据作用域的模式状态进行隐藏

getSettings可能存在的问题是,您每次都在那里启动一个get调用,我猜您希望在整个应用程序中执行一次。
因此,数据应该缓存在MainService中,所以第二次应该返回第一次调用的承诺。

这种行为的原因是服务调用的异步性质。假设OtherController是嵌套控制器并与MainController共享作用域。您可以使用手表检查数据何时可供其他控制器使用:

使用.getSettings.then也可以,但是每次发出新请求时,都应该缓存远程响应


另一个选项是使用$routeProvider解析配置将此数据传递给MainController。在这种情况下,仅当设置数据可用时,才会加载主控制器。查看解决方案和示例以了解如何完成。

感谢您的回答。你是对的,我不想在我的应用程序中多次调用getSettings。是的,我想禁用UI,但我更喜欢它被延迟。顺便说一句,它是一个模式,理想情况下,我希望它仅在数据可用时出现。因此,使用ng class={hidden:dataLoading}或其他方法,并在css中添加一个名为hidden的类,该类显示为:none。只是为了解释一下,在加载数据时,您的UI将隐藏,第二次调用应返回缓存的数据,您应将其保存在服务中,因此,任何未来的呼叫都应该立即获取数据。如果你需要更多的信息,我可以解释或举个例子,但我觉得你有这个想法。我理解你说的,但我不知道如何实施它。promise对象仅在MainController中调用,它不知道是否存在其他控制器,即控制modal的控制器。当用户单击时如何显示,但仅当数据可用时显示,如果数据不可用,则在其他控制器中的数据可用后显示。谢谢你的帮助!因此,您可以在服务函数中返回svc.settings,并在另一个控制器中监视$resolved属性,如:$scope.$watch'settings.$resolved',函数{if$scope.setting!==undefined&&$scope.setting.$resolved{//我从GET}获取了数据;