AngularJS 将 lastTime 传递给服务以仅显示最近的帖子
AngularJS passing lastTime to a service to display only recent posts
我不确定我这样做是否正确,但我想要实现的是类似 Twitter 提要的效果。
我有一个状态页面,在第一个页面加载时它会获取所有状态,然后它只会在页面上显示更新。
我有一个调用 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 以便我可以使用它来仅获取任何更新,然后以某种方式将它们推送到视图?
非常感谢任何帮助、教程等。
构建服务时,尽量将所有 "service-related" 功能保留在服务范围内。这将有助于减少您的控制器在长期 运行 中的占用空间。此外,重要的是要了解 "promises" 默认情况下在整个 angular 框架中使用。在这种情况下,$http 服务已经 returns 承诺。
请在下方查看您的服务:
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" 只是 returns $http 方法?请注意我是如何开始在这里封装所有 "polling" and/or "recursion" 逻辑的。这指的是我原来的说法,"Try and keep all service-related code in our service scope".
请在下方检查您的控制器:
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 已经返回承诺。
对于您的 "polling",不是创建间隔实例,而是执行超时。这是一种更合适的递归方法,因为您不会创建任何不必要的间隔循环。
最后,递归的所有逻辑(ig "how many times it should run" 和 "when should it stop")都保存在服务中。这是因为它与服务有关。
您还可以通过将 "periodic" 刷新移动到该服务来更进一步。同样,主要是因为它只是服务逻辑。
结果:
在 10 次尝试的过程中,您的 api/feed 将每 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();
}];
这些小改动不会解决您所有的问题。您将需要依靠您的服务器来返回仅在时间戳之后创建的结果。
我不确定我这样做是否正确,但我想要实现的是类似 Twitter 提要的效果。
我有一个状态页面,在第一个页面加载时它会获取所有状态,然后它只会在页面上显示更新。
我有一个调用 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 以便我可以使用它来仅获取任何更新,然后以某种方式将它们推送到视图?
非常感谢任何帮助、教程等。
构建服务时,尽量将所有 "service-related" 功能保留在服务范围内。这将有助于减少您的控制器在长期 运行 中的占用空间。此外,重要的是要了解 "promises" 默认情况下在整个 angular 框架中使用。在这种情况下,$http 服务已经 returns 承诺。
请在下方查看您的服务:
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" 只是 returns $http 方法?请注意我是如何开始在这里封装所有 "polling" and/or "recursion" 逻辑的。这指的是我原来的说法,"Try and keep all service-related code in our service scope".
请在下方检查您的控制器:
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 已经返回承诺。
对于您的 "polling",不是创建间隔实例,而是执行超时。这是一种更合适的递归方法,因为您不会创建任何不必要的间隔循环。
最后,递归的所有逻辑(ig "how many times it should run" 和 "when should it stop")都保存在服务中。这是因为它与服务有关。
您还可以通过将 "periodic" 刷新移动到该服务来更进一步。同样,主要是因为它只是服务逻辑。
结果:
在 10 次尝试的过程中,您的 api/feed 将每 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();
}];
这些小改动不会解决您所有的问题。您将需要依靠您的服务器来返回仅在时间戳之后创建的结果。