$ q.all不按预期工作

问题描述:

这就好像有一个加载div,我想显示如果两个API调用还没有准备好结果。

因此,突然的结果不会跳入视图导致它闪烁。

我的观点看起来是这样的:

<div ng-show="vm.loading" class="table-overlay table-overlay-loading"> 
    <div class="table-overlay-content"> 
     <div class="table-overlay-message">Loading&hellip;</div> 
    </div> 
</div> 
<div ng-show="vm.loadError" class="table-overlay table-overlay-error"> 
    <div class="table-overlay-content"> 
     <div class="table-overlay-message"><i class="icon-error-indicator"></i> 
      Error encountered. Please try again. 
     </div> 
    </div> 
</div> 
<div class="inner" ng-show="!vm.loading && !vm.loadError"> 
    <div class="info-panel"> 
     <h3>Current Pricing</h3> 
     <p> 
      Billing Period: 
      <br> 
      <em>{{vm.invoiceCoverageStartDate}} to {{vm.invoiceCoverageEndDate}}</em> 
      <br> 
      <big><b>${{vm.invoiceTotal}}</b>/month</big> 
      <br> 
      <a href=""><small>(See Details)</small></a> 
     </p> 
    </div> 

而且方法来填充interpolated values样子:

 vm.getCurrentPricingDetails = function(){ 
      HttpWrapper.send(url1, {"operation":'GET'}) 
      .then(function(result){ 
       console.log("Current Pricing Response: ", result); 
       vm.invoiceCoverageStartDate = $filter('date')(result.invoice.coverageStartDate, "dd/MM/yyyy"); 
       vm.invoiceCoverageEndDate = $filter('date')(result.invoice.coverageEndDate, "dd/MM/yyyy"); 
       vm.invoiceTotal = result.invoice.invoiceTotal; 
      }, function(error) { 
       console.log("Error: Could not fetch current pricing details", error); 
      }); 
     } 


     vm.getProjectedPricing = function(){ 
      $timeout(function(){ 
       var selectedPricingMappingObj = dataStoreService.getItems('server'); 
       selectedPricingMappingObj.forEach(function(item){ 
        vm.totalProjectedPricingSum += parseFloat(item.selectedMapping.cost); 
       }); 
       vm.totalProjectedPricingSum = vm.totalProjectedPricingSum.toFixed(2); 
      },1000);         
     } 

但在我的组件$onInit method I tried to resolve the same using promise.

 vm.$onInit = function() {     
      vm.loading = true; 
      vm.loadError = false; 
      var currentPricingDetails = vm.getCurrentPricingDetails(); 
      var projectedPricingDetails = vm.getProjectedPricing(); 

      $q.all([currentPricingDetails,projectedPricingDetails]).then(function(results) { 
       debugger; 
       vm.loading = false; 
      }, function(error){ 
       debugger; 
       vm.loading = false; 
       vm.loadError = true; 
      }); 

但仍是屏幕闪烁和loading div没有显示。

我想loading div显示之前,除非这两个方法调用不与results.`

做如何做到这一点?

我在做什么错?

+0

要么'getCurrentPricingDetails'和'getProjectedPricing'没有返回任何承诺,以便默认'$ q.all()'行为是考虑解析对象,而不是承诺。 –

vm.getCurrentPricingDetails()和vm.getProjectedPricing()不回报什么。所以,你的行

$q.all([currentPricingDetails,projectedPricingDetails]) 

真的只是

$q.all([undefined, undefined]) 

$ q.all预期承诺的数组。 $ timeout在完成时返回一个承诺。看起来你的HttpWrapper也会返回一个承诺。所以我认为,所有你需要做的就是回报添加到您的代码:

return HttpWrapper.send(url1, {"operation":'GET'}) 

return $timeout(function(){ 
+0

完全忘记$超时和$ http返回承诺自己 - 这是最好的解决方案! –

+0

@霍夫兹这么一分钟,但我错过了重要的一面。感谢您的努力。 – StrugglingCoder

vm.getCurrentPricingDetails和vm.getProjectedPricing没有返回的承诺,因此$ q.all没有机会知道何时完成

m.getCurrentPricingDetails = function(){ 
     var defer = $q.defer(); 
     HttpWrapper.send(url1, {"operation":'GET'}) 
     .then(function(result){ 
      console.log("Current Pricing Response: ", result); 
      vm.invoiceCoverageStartDate = $filter('date')(result.invoice.coverageStartDate, "dd/MM/yyyy"); 
      vm.invoiceCoverageEndDate = $filter('date')(result.invoice.coverageEndDate, "dd/MM/yyyy"); 
      vm.invoiceTotal = result.invoice.invoiceTotal; 
      defer.resolve(); 
     }, function(error) { 
      console.log("Error: Could not fetch current pricing details", error); 
      defer.reject(); 
     }); 
     return defer.promise; 
    } 


    vm.getProjectedPricing = function(){ 
     var defer = $q.defer(); 
     $timeout(function(){ 
      var selectedPricingMappingObj = dataStoreService.getItems('server'); 
      selectedPricingMappingObj.forEach(function(item){ 
       vm.totalProjectedPricingSum += parseFloat(item.selectedMapping.cost); 
      }); 
      vm.totalProjectedPricingSum = vm.totalProjectedPricingSum.toFixed(2); 
      defer.resolve(); 
     },1000); 
     return defer.promise;        
    }