0

我不確定是否以正確的方式進行此操作,但是我想實現的是類似於Twitter的Feed。AngularJS將lastTime傳遞給服務以僅顯示最近發佈的內容

我有一個狀態頁面,在第一頁加載它將獲得所有狀態,然後它將只顯示頁面上的更新。

我有一個調用的API服務:

emp.services.SocialService = ['$http', '$q', function ($http, $q) { 

    var deferred = $q.defer(); 

    $http.get('/api/feed').then(function (data) { 
     deferred.resolve(data); 
    }); 

    this.getStatuses = function() { 
     return deferred.promise; 
    }; 

    return { 
     getStatuses: this.getStatuses 
    }; 

}]; 

而且我的控制器:

emp.controllers.StatusesController = ['SocialService', '$scope', '$interval', function(SocialService, $scope, $interval) { 

    $scope.statuses = []; 
    $scope.lastTime = 0; 

    $scope.refreshStatuses = function() { 

     var statuses = SocialService.getStatuses(); 

     statuses.then(function(data) { 

      $scope.statuses = data.data; 

      for(id in $scope.statuses) { 

       item = $scope.statuses[id]; 

      } 

     }); 
    }; 

    $scope.periodicRefresh = function() { 
     $scope.refreshStatuses(); 
     $interval($scope.periodicRefresh, dataInterval, true); 
    }; 

    $scope.periodicRefresh(); 



}]; 

可能有人請看看這個,讓我知道我怎麼能改善它,推僅更新視圖。我假設我還需要以某種方式將lastTime傳遞給API URL,以便我可以使用它只抓取任何更新,然後以某種方式將這些更新推送到視圖中?

任何幫助,教程等非常感謝。

+0

您的SocialService有一個市長問題。您僅在服務初始化時創建一個http,並始終在getStatuses函數中返回相同的承諾。承諾只能解決一次。 – Michael

+0

在每個http服務請求中存儲服務中的lastUpdate時間,然後在每個更新請求中添加此值作爲參數。 – Michael

+0

感謝Micheal,當談到這些新的前端框架時,我是一個完整的noob,你介意提供一個代碼示例,說明什麼是我的http請求的正確方法,以及時間的傳遞等?希望我可以從中學到:) – ChrisBratherton

回答

2

建立服務時,請嘗試在服務範圍內保留所有「服務相關」功能。這將有助於長期減少您的控制器佔地面積。另外,默認情況下,在整個角框架中使用「承諾」是很重要的。在這種情況下,$ 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(); 


}]; 

這些小的變化不會解決所有問題的。您將需要依靠您的服務器返回僅在時間戳後創建的結果。

+0

這是完美的,真的很好,真的很好!但是,我可以看到這會變得有點緩慢,因爲可能有數百個狀態,並且每次刷新時都會讓它們全部變爲現實。現在,有沒有辦法修改上面的代碼以將可能的lastId或lastTime傳遞給API,然後api將僅檢索在此時間之後創建的記錄,並且Angular會將它們'推送'到$ scope.statuses數組? – ChrisBratherton

+0

我希望這是有道理的?把它想象成一個Twitter風格的feed,但不是點擊X New Updates鏈接,它會自動拖動新的並將它們粘貼在頁面頂部:) – ChrisBratherton

+0

配合,編輯完美,完全符合我的需求!我現在可以看到我現在出錯的地方,我之前已經嘗試過,但是你有.push.apply的地方,我沒有添加.apply。謝謝您的幫助! – ChrisBratherton

相關問題