【问题标题】:Unexpected behaviors of promises承诺的意外行为
【发布时间】:2015-05-28 19:38:59
【问题描述】:

我在与 Factory/Service 合作时遇到了麻烦。我为我的所有 AJAX 调用创建了一个 AjaxRequests 工厂。我的工厂代码是

.factory('AjaxRequests', ['$http', function ($http) {
                return {
                    getCampaignsData: function () {
                        var campaigns
                        return $http.get(url).then(function (response) {
                            campaigns = response.data;
                            return campaigns;
                        });

                    }
                }
            }])

我创建了另一个服务,我在其中注入了这个工厂。我的服务代码

.service('CampaignsService', ['$rootScope', 'AjaxRequests', function ($rootScope, AjaxRequests) {
     this.init = function () {
     this.camps;
     AjaxRequests.getCampaignsData().then(function (response) {
       this.camps = response.campaigns;
       console.log(this.camps); // It is showing data
     })
     console.log(this.camps); // But it is not working :(
    };
   this.init();

}])

在我的控制器中

.controller('AdvanceSettingsController', ['$scope', 'CampaignsService', function ($scope, CampaignsService) {
                $scope.CampaignsService = CampaignsService;
            }
        ])

我已阅读此article 以了解承诺,但它在这里不起作用。我可以直接在控制器中实现它并且它工作正常。但它认为使控制器变粗是一种不好的编码标准。但是当我使用服务和工厂时,我卡住了。 我的问题是为什么我没有在我的整个服务中使用 ajax 数据? 我需要在我的视图模板以及我的整个休息脚本中使用CampaignsService.camps,但每次我得到@987654327 @。这里发生了什么?我以前问过同样的问题,但没有成功。 请有人帮助我了解承诺以及如果我正在工作,为什么会出现这种类型的错误?这种类型的问题已经被问过before,但它在控制器中工作。可能是因为我在服务中使用它而被卡住了。

提前非常感谢。

【问题讨论】:

  • 根据我的经验你不需要CampaignsService,你应该直接在你的控制器中使用AjaxRequests.getCampaignsData().then(function (response) { $scope.camps = response.campaigns; })
  • 好的,那我可以做些什么。实际上,我已经在此服务中包含了我的完整代码,但在我处理静态数据之前。我在使用服务时卡住了

标签: angularjs


【解决方案1】:

这不是错误或一些棘手的功能。就像在任何其他 AJAX 实现中一样,您只能在 AngularJS 的 $http success 方法中访问响应数据。这是因为异步 JavaScript 和 XML 的异步特性。

你所拥有的正在发挥作用。

.controller('AdvanceSettingsController', ['$scope', 'AjaxRequests', function ($scope, AjaxRequests) {
        $scope.camps = [];
        AjaxRequests.getCampaignsData().then(function(data) {
             $scope.camps = data;
        });
    }
])

然后绑定camps:

<div ng-repeat="camp in camps>{{camp.name}}</div>

在您的实现中不好的是,您不是在服务中对相关内容进行分组,而是为所有内容编写了一个大的AjaxRequests 服务。你应该有一个 CampaignsService 有一个 getData 方法并将它注入你的控制器。

为什么会这样?因为$http 为您做了一个$scope.$apply,它在数据加载(then) 之后触发一个摘要循环并更新HTML。所以在then 回调之前ng-repeat[]after 一起运行它再次运行,但使用来自响应的数据,因为您正在设置$scope.camps = data;

&lt;div ng-repeat="camp in CampaignsService.camps&gt;{{camp.name}}&lt;/div&gt;不起作用的原因是function variable scoping

then 回调内部的 this 引用与外部的 this 引用不同。

这将起作用并使用常见的var self = this 技巧:

var self = this;
this.camps = [];
this.init = function () {
    AjaxRequests.getCampaignsData().then(function (response) {
        // here "this" is not the one from outside.
        // "self" on the other hand is!
        self.camps = response.campaigns;
    });
};

【讨论】:

  • 非常感谢分享这些有用的信息。我明白了你的意思,我会根据你提到的改变我的代码结构,但这是我的最后一个问题。为什么 $scope.CampaignsService = CampaignsService;在控制器中不起作用?
  • 它正在使用除 $http 服务之外的其他功能。如果我的另一个函数更改了任何对象并且我正在使用该对象,那么通过使用上面的行,摘要循环会自动开始。
  • 非常感谢 Sergiu 先生。
猜你喜欢
  • 1970-01-01
  • 2016-10-06
  • 2022-07-05
  • 2023-01-26
  • 2019-06-18
  • 2017-08-22
  • 1970-01-01
  • 1970-01-01
  • 2015-05-12
相关资源
最近更新 更多