AngularJS将lastTime传递给服务以仅显示最近的帖子

AngularJS将lastTime传递给服务以仅显示最近的帖子,angularjs,angularjs-scope,angularjs-service,angularjs-controller,Angularjs,Angularjs Scope,Angularjs Service,Angularjs Controller,我不确定这是否是正确的方式,但我想实现的是类似推特的效果 我有一个状态页面,在第一次加载页面时,它将获得所有状态,然后它将只在页面上显示更新 我有一个调用API的服务: emp.services.SocialService = ['$http', '$q', function ($http, $q) { var deferred = $q.defer(); $http.get('/api/feed').then(function (data) { deferr

我不确定这是否是正确的方式,但我想实现的是类似推特的效果

我有一个状态页面,在第一次加载页面时,它将获得所有状态,然后它将只在页面上显示更新

我有一个调用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();



}];
有人可以看看这个,让我知道我可以如何改进它,推更新只到视图。我假设我还需要以某种方式将最后一次传递到API URL,以便我可以使用它只获取任何更新,然后以某种方式将这些更新推送到视图


非常感谢您的帮助、指导等

构建服务时,请尝试将所有“服务相关”功能保留在服务范围内。从长远来看,这将有助于减少控制器占用的空间。此外,理解默认情况下在angular框架中使用“承诺”也是很重要的。在本例中,$http服务已经返回承诺

请在下面查看您的服务:

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();

}];
您的代码使用了一些我不理解的变量。例如,“数据间隔”和“项目”。它们被使用但从未定义过

“刷新状态”是相同的代码。它看起来和你以前的几乎一模一样。它甚至可以使用“then”方法。同样,由于$http已经返回承诺

对于“轮询”,不要创建间隔实例,而是执行超时。这是一种更合适的递归方法,因为您不会创建任何不必要的间隔循环

最后,递归的所有逻辑(ig“应该运行多少次”和“应该何时停止”)都保存在服务中。这是因为它属于服务

您还可以通过将“定期”刷新移动到服务来进一步实现这一点。同样,这主要是因为它只是服务逻辑

结果是:

在10次尝试的过程中,您的api/提要将每1秒获取一次

请检查存在未定义变量的区域

角度将触发它的消化循环。每次刷新运行时,您的状态都将更新


编辑:为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();


}];

这些小小的改变并不能解决你所有的问题。您需要依靠服务器返回仅在时间戳之后创建的结果。

您的社交服务存在一个问题。您仅在服务初始化时创建http,并在getStatuses函数中始终返回相同的承诺。承诺只能解决一次。在每个http服务请求中,将上次更新时间存储在服务中,然后在每个更新请求中添加此值作为参数。谢谢,Micheal,对于这些新型前端框架,我是一个彻头彻尾的傻瓜,您是否介意提供一个代码示例,说明在处理http请求以及时间的流逝等问题时,正确的方法是什么?希望我能从中学到:)@TheRabbitFactory你应该自己尝试一些东西,用你尝试过的代码询问它是否有效。这里有一个小示例/希望这对你有所帮助。这是完美的,工作真的,真的很好!然而,我可以看到这变得有点慢,因为可能有数百个状态,每次刷新都会得到它们。现在,有没有一种方法可以修改上面的代码,将lastId或lastTime传递给API,API将只检索在此时间之后创建的记录,Angular将“推”到$scope.statuses数组?我希望这是有意义的?可以把它想象成一个Twitter风格的feed,但它不会点击X New Updates链接,而是自动提取新的更新并将其粘贴在页面顶部:)伙计,编辑非常完美,完全符合我的需要!我可以看出我现在哪里出了问题,我以前确实尝试过这个,但是你有。推。应用。我没有添加。应用。谢谢你的帮助!