AngularJS将lastTime传递给服务以仅显示最近的帖子
我不确定这是否是正确的方式,但我想实现的是类似推特的效果 我有一个状态页面,在第一次加载页面时,它将获得所有状态,然后它将只在页面上显示更新 我有一个调用API的服务: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
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链接,而是自动提取新的更新并将其粘贴在页面顶部:)伙计,编辑非常完美,完全符合我的需要!我可以看出我现在哪里出了问题,我以前确实尝试过这个,但是你有。推。应用。我没有添加。应用。谢谢你的帮助!