我遵循了这里发送的优秀建议(Server polling with AngularJS),但[我认为]有时需要取消轮询,以后再恢复。
具体来说,我有一个数据列表。客户端每隔5秒轮询一次服务器,其时间戳为“上次同步” - 它最后一次与服务器共享。服务器响应自该时间戳以来的任何更改。
有时客户端可能会自行更改,将PUT发送到服务器。
我认为PUT请求存在问题,干扰轮询(反之亦然),导致数据不同步。我想通过取消轮询来测试这个,直到PUT请求被批准为止。但是我无法到达轮询功能每次都可以成功调用自己的地方;发出可以取消的承诺;并在取消后重新启动。
我与服务(“pulseService”)有点关系,但我不能一路走来。它看起来像这样,但失败了“无法读取未定义的属性'轮询'”:
myModule.factory('pulseService', function($http, $rootScope, $timeout) {
$rootScope.pulsePromise = null;
var obj = {
poller: function() {
var thing = this;
console.log("Here I am!");
var semaphore = new Date().getTime();
var query = {"timestamp": {'$gt': semaphore}};
query = JSON.stringify(query);
$http({method: 'GET', url: '/registrants', data: query}).
success(function(data, status, headers, config) {
$rootScope.error = false;
$rootScope.$broadcast('pollFinished', data);
$rootScope.pulsePromise = $timeout(thing.poller, 5000);
}).
error(function(data, status, headers, config) {
$rootScope.error = true;
semaphore = new Date().getTime();
$rootScope.pulsePromise = $timeout(thing.startPolling, 15000);
});
}(),
startPolling: function() {
console.log(this);
this.poller;
}
};
return obj;
});
根据要求,这是我的控制器的简化版本..它可能有一点kruft但我试图简化一些东西:
function regCtrl($scope, $http, $rootScope, $timeout, pulseService) {
// ...
// Doing stuff to initialize and gather data into $scope.attendees
$scope.$on( 'pollFinished', function( event, data ) {
var found = false;
angular.forEach(data, function(resultVal, resultKey) {
while (found === false) {
angular.forEach($scope.attendees, function(attendeeVal, attendeeKey) {
if (attendeeVal.id == resultVal.id) {
$scope.attendees[attendeeKey] = resultVal;
found = true;
}
});
}
found = false;
});
});
// .. Logic for pushing a change to the server
// .....
$timeout.cancel($rootScope.pulsePromise);
$http({method: 'PUT', url: '/registrants/'+attendee.id, data: query }).
success(function(data, status, headers, config) {
attendee.isHere = data.isHere;
console.log("rerunning");
}).
error(function(data, status, headers, config) {
$scope.error = true;
});
// ...
var semaphore = new Date().getTime();
// Kickoff the polling process
pulseService.startPolling();
}
regCtrl.$inject = ['$scope','$http','$rootScope','$timeout','pulseService'];
答案 0 :(得分:1)
我认为你得到的具体错误是因为,当你执行$ timeout(thing.startPolling,15000)时,startPolling是未绑定的。所以startPolling里面的“this”是未定义的。
我认为你可以用$ timeout(obj.poller,...)替换两个$ timeout调用,并摆脱startPolling。
或者你可以绑定像$ timeout(thing.poller.bind(thing),5000)这样的方法。