调用服务功能:首次执行时不填充范围

时间:2016-10-03 16:48:44

标签: javascript angularjs

我正在重构一些angularjs代码以使控制器更精简并将一些逻辑移动到服务中。

旧代码这样就行了。

在控制器......

var firmSearchRequest = {
    type : "ByDate",
    startDate : $scope.startDate,
    endDate : $scope.endDate
};

firmService.getFirms(firmSearchRequest).then(function(response) {           
    firmService.appendFirmList(response.data);          
    $scope.firmList = firmService.getFirmList();
});

在服务中......

var firmList = [];

    this.getFirms = function(firmSearchRequest) {
        return httpService.putForResponse('firms/search', firmSearchRequest);
    };


    this.appendFirmList = function(newfirmList){
        firmList = firmList.concat(newfirmList);
    }


    this.getFirmList = function() {
        return firmList;
    };

重构代码无法按预期工作

在控制器......

var firmSearchRequest = {
    type : "ByDate",
    startDate : $scope.startDate,
    endDate : $scope.endDate
};

$scope.firmList = firmService.appendFirmListByDate(firmSearchRequest);

在服务中......

var firmList = [];

    this.appendFirmListByDate = function(firmSearchRequest){

        this.getFirms(firmSearchRequest).then(function(response) {          
            firmList = firmList.concat(response.data);
        });

        return firmList;

    };

    this.getFirms = function(firmSearchRequest) {
        return httpService.putForResponse('firms/search', firmSearchRequest);
    };

意外行为

对于重构代码,当我单击执行上述代码的按钮时,我没有收到控制台错误,但$scope.firmList为空。当我再次单击该按钮进行第二次执行时,$scope.firmList被正确填充。

为什么第一次执行无法正常工作?我做错了什么?

3 个答案:

答案 0 :(得分:1)

在您的控制器中

$scope.firmList = firmService.appendFirmListByDate(firmSearchRequest);

这里函数 firmService.appendFirmListByDate()是一个简单的函数,它会同步运行,所以会立即返回值,所以在这种情况下返回的值是名为 firmList的空数组

所以问题就出现了为什么当你第二次点击按钮时得到正确的列表。

  • 当您第二次单击该按钮时,插入了数组 var firmList = [] 中的值,因为第一次运行的承诺是

    this.getFirms(firmSearchRequest).then(function(response) {          
        firmList = firmList.concat(response.data);
    });
    
  • 当您第二次单击该按钮时,该功能仍然会同步运行,并且您获得了第一步填充的值。

注意 - 所以每当你获得一个由最后一步中的承诺填充的值时。

重点

  • 您无法以这种方式重构代码

  • 制作一个瘦控制器并不意味着删除它的承诺。这意味着业务逻辑不应该存在。所以你的承诺应该是内部服务,应该向控制器返回一个承诺,数据操作等应该在服务中完成

从服务中退回承诺

this.appendFirmListByDate = function(firmSearchRequest){
   return new Promise(function(resolve,reject){
        //if firmList contains data then just return it
        if(firmList.length!==0){
               resolve(firmList);
         }else{
            this.getFirms(firmSearchRequest).then(function(response) {          
               firmList = firmList.concat(response.data);
               resolve(firmList);
            }).catch(function(error){
                  reject(error);
            });
        }

    });
};

答案 1 :(得分:0)

你是不是在尝试返回firmList之前(技术上无论是否)承诺完成了?

您应该将回报置于承诺内,或者可以返回承诺。

答案 2 :(得分:0)

您可以使用callaback功能

<强>服务

this.appendFirmListByDate = function(firmSearchRequest, fct){
    this.getFirms(firmSearchRequest).then(function(response) {          
        fct(firmList.concat(response.data);)
    });
};

<强>控制器

firmService.appendFirmListByDate(firmSearchRequest, function(result){
    $scope.firmList = result;
});