2015-09-11 37 views
2

我想通過angularjs中的promise來從API獲取一些數據。我有一個從API獲取價值並將承諾返回給控制器的服務。然後(功能)沒有得到angularjs中的返回的承諾值更新

***Service*** 
this.forgotPasswordLink = function(email){ 
    var deferred = $q.defer(); 
    $http.post('/forgotPassword',{ 
     email: email 
    }).success(function(response){ 
     console.log("the new response is: ",response); 
     deferred.resolve(response); 
    }).error(function(error){ 
     deferred.reject(error); 
    }); 
    return deferred.promise; 
}; 

**Controller** 
authService.forgotPasswordLink($scope.forgotPasswordEmail).then(function(data){ 
     console.log(data); 
     if(data.message === 'emailFound'){ 
      $scope.emailSent = true; 
      $scope.emailNotSent = false; 
     } 
     else{ 
      $scope.emailNotSent = true; 
      $scope.emailSent = false; 
     } 
    }); 

這裏authservice是服務的名稱。所以這段代碼工作正常,但問題是當我嘗試多次獲取數據,第一次承諾返回正確的數據,但是當我嘗試使用不同的數據發佈時,承諾不會更新那麼(功能),即使承諾從服務器獲得適當的響應。

如果您看到有兩個控制檯語句,一個在服務中,另一個在控制器中;因此控制器中的控制檯語句首先被執行,因爲promise會返回舊值,並且當promise被解析時,正在服務的第二個控制檯語句將使用更新後的值執行。

那麼如何獲得更新後的值(函數)。發佈數據後需要刷新服務嗎?

+1

我相信'.post()'本身就會返回一個promise,所以不需要創建一個新的延遲對象。另外,你應該使用'.then()'作爲成功處理程序,而不是'.success'。您可以簡單地使用'return $ http.post(...)'而不用實際鏈接任何方法,因爲您將評估控制器中的承諾。 – Terry

+0

你確定http請求沒有返回錯誤響應嗎? –

+0

你是說調用'authService.forgotPasswordLink(「email1」)'然後'authService.forgotPasswordLink(「email2」)'返回相同的結果嗎? –

回答

-1

當你使用then方法時,你已經把.data放在你的變量data.data後面。

0

正如@Terry建議的那樣,您根本不必依賴$ q來獲得結果。我推薦以下兩種方法之一:

#1:

***Service*** 
this.forgotPasswordLink = function(email){ 
    return $http.post('/forgotPassword',{ 
     email: email 
    }).then(function(response){ 
     console.log("the new response is: ",response); 
     return response; 
    }).catch(function(error){ 
     return error; 
    }); 
}; 

在這種情況下,控制器保持不變;唯一需要注意的是,即使在錯誤的情況下,控制器的當時的函數將被調用,data是從服務的catch塊返回的錯誤對象。

#2:

***Service*** 
this.forgotPasswordLink = function(email){ 
    return $http.post('/forgotPassword',{ 
     email: email 
    }); 
}; 

***Controller*** 
authService.forgotPasswordLink().then(function(data){ 
    console.log(data); 
    if(data.message === 'emailFound'){ 
     $scope.emailSent = true; 
     $scope.emailNotSent = false; 
    } 
    else{ 
     $scope.emailNotSent = true; 
     $scope.emailSent = false; 
    } 
}).catch(function(error){ 
    console.log(error); // Error handling like notifying user, etc... 
}); 

在第二種方法中,該服務僅返回由$http返回的承諾。控制器然後根據這個承諾的結果採取行動。

有人可能會爭辯說,獲取數據並將其交給控制器採取行動是服務的責任。這是第一種方法。

我個人比較喜歡第一種方法,因爲服務很簡單,而且很容易以這種方式進行測試。