建立服務時,請嘗試在服務範圍內保留所有「服務相關」功能。這將有助於長期減少您的控制器佔地面積。另外,默認情況下,在整個角框架中使用「承諾」是很重要的。在這種情況下,$ http服務已經返回promise。
請查看以下服務:
emp.services.SocialService = ['$http', function ($http) {
var totalRefreshCount = 10,
currentRefreshCount = 0;
function getStatuses() {
return $http.get('/api/feed');
};
function updateTotalRefreshCount() {
currentRefreshCount = currentRefreshCount + 1;
return currentRefreshCount;
}
function shouldRunAgain() {
return totalRefreshCount >= currentRefreshCount;
}
function resetCounter() {
currentRefreshCount = 0;
return;
}
return {
getStatuses: getStatuses,
shouldRunAgain: shouldRunAgain,
updateTotalRefreshCount: updateTotalRefreshCount,
resetCounter: resetCounter
};
}];
注意如何 「getStatuses」 僅返回$ HTTP方法?注意我在這裏也開始封裝所有的「輪詢」和/或「遞歸」邏輯。這涉及我的原始聲明,「嘗試並將所有與服務相關的代碼保留在我們的服務範圍內」。
請查看以下控制器:
emp.controllers.StatusesController = ['SocialService', '$scope', '$timeout', function(SocialService, $scope, $timeout) {
var dataInterval = 1 // in seconds;
$scope.statuses = [];
$scope.refreshStatuses = function() {
SocialService.getStatuses().then(function(data) {
$scope.statuses = data.data;
});
};
$scope.periodicRefresh = function() {
$scope.refreshStatuses();
if (!SocialService.shouldRunAgain())
return;
$timeout(function(){
$scope.periodicRefresh();
SocialService.updateTotalRefreshCount();
}, dataInterval * 1000);
};
SocialService.resetCounter();
$scope.periodicRefresh();
}];
有一些變數,你的代碼使用的是,我不明白。例如,「dataInterval」和「item」。他們被使用,但從未定義...
「refreshStatuses」是相同的代碼。它看起來幾乎和你以前的一樣。它甚至可以用「then」方法工作。同樣,由於$ http已經返回承諾。
對於您的「輪詢」,而不是創建間隔實例,請改爲執行超時。這是遞歸更合適的方法,因爲您不會創建任何不必要的間隔循環。
最後,遞歸的所有邏輯(ig「它應該運行多少次」以及「何時應該停止」)被保存在服務中。這是因爲它與服務有關。
您可以通過將「定期」刷新移動到服務來做進一步處理。同樣,主要是因爲它只是服務邏輯。
其結果是:
您的API /進料將被取爲10次的過程中每隔1秒。
請檢查未定義變量的區域。
Angular會觸發它的消化週期。每次刷新運行時,狀態都會更新。
編輯:添加API
emp.services.SocialService = ['$http', function ($http) {
var totalRefreshCount = 10,
currentRefreshCount = 0,
timeStamp = null;
function getStatuses() {
// generate query param
var query = timeStamp === null ? "" : "?ts=" + timeStamp.toJSON();
// update/create time stamp
timeStamp = new Date();
return $http.get('/api/feed' + query);
}
function updateTotalRefreshCount() {
currentRefreshCount = currentRefreshCount + 1;
return currentRefreshCount;
}
function shouldRunAgain() {
if (totalRefreshCount >= currentRefreshCount) {
updateTotalRefreshCount();
return true;
}
return false;
}
function resetCounter() {
currentRefreshCount = 0;
timeStamp = null;
return;
}
return {
getStatuses: getStatuses,
shouldRunAgain: shouldRunAgain,
resetCounter: resetCounter
};
}];
時間戳 「getStatuses」 將包含每當一個新的請求時時間戳查詢參數。
我們的控制器僅略微改變:
emp.controllers.StatusesController = ['SocialService', '$scope', '$timeout', function(SocialService, $scope, $timeout) {
var dataInterval = 1 // in seconds;
$scope.statuses = [];
$scope.refreshStatuses = function() {
SocialService.getStatuses().then(function(data) {
// appends new array to existing.
$scope.statuses.push.apply($scope.statuses, data.data);
});
};
$scope.periodicRefresh = function() {
$scope.refreshStatuses();
if (!SocialService.shouldRunAgain())
return;
$timeout($scope.periodicRefresh(), dataInterval * 1000);
};
SocialService.resetCounter();
$scope.periodicRefresh();
}];
這些小的變化不會解決所有問題的。您將需要依靠您的服務器返回僅在時間戳後創建的結果。
您的SocialService有一個市長問題。您僅在服務初始化時創建一個http,並始終在getStatuses函數中返回相同的承諾。承諾只能解決一次。 – Michael
在每個http服務請求中存儲服務中的lastUpdate時間,然後在每個更新請求中添加此值作爲參數。 – Michael
感謝Micheal,當談到這些新的前端框架時,我是一個完整的noob,你介意提供一個代碼示例,說明什麼是我的http請求的正確方法,以及時間的傳遞等?希望我可以從中學到:) – ChrisBratherton