I have a quiz app with a controller where I should set up a timer that should be counting for 30s, and then stop the quiz if there is no activity in that time. If there is some activity in the meantime it should be reset and start counting again. I have set up web socket listeners for that. How should I do the timer setup?
我有一个带控制器的测验应用程序,我应该设置一个应该计数30秒的计时器,然后在那段时间没有活动时停止测验。如果在此期间有某些活动,则应重置并再次开始计数。我为此设置了Web套接字侦听器。我该如何设置定时器?
This is my controller:
这是我的控制器:
angular.module('quiz.controllers')
.controller('MultiPlayerQuestionController', function(
$scope,
$rootScope,
$state,
$stateParams,
$timeout,
UserService,
QuizService,
InviteService,
MessageService,
SocketService
) {
$scope.user = UserService.get();
$scope.quiz = QuizService.getCurrent();
$scope.opponent = $scope.user.player.id == $scope.quiz.players[0].id
? $scope.quiz.players[1]
: $scope.quiz.players[0]
|| null;
$scope.currentQuestion = {};
$scope.answer = {};
$scope.showAlternatives = false;
$scope.showCorrect = false;
$scope.isLast = false;
$scope.opponentAnswered = false;
var timeouts = {
stop: null,
activate: null
};
var startTime,
loadBar,
initiated = false;
// Opponent has answered; update score display
SocketService.socket.removeAllListeners('gameEvent:opponentAnswer');
SocketService.socket.on('gameEvent:opponentAnswer', function(message) {
$scope.opponentAnswered = true;
QuizService.updateOpponentScore(message.data.totalScore);
});
// Next question is triggered from all players having answered
SocketService.socket.removeAllListeners('gameEvent:nextQuestion');
SocketService.socket.on('gameEvent:nextQuestion', function(message) {
$timeout(function() {
QuizService.setCurrentQuestion(message.data.question);
setupQuestion(message.data.question);
}, 3000);
});
// Game is finished, go to score screen
SocketService.socket.removeAllListeners('gameEvent:quizFinished');
SocketService.socket.on('gameEvent:quizFinished', function(message) {
stopQuiz();
$timeout(function() {
$state.go('multiplayer.score');
}, 3000);
});
// An opponent has quit, go to score screen
SocketService.socket.removeAllListeners('gameEvent:opponentQuit');
SocketService.socket.on('gameEvent:opponentQuit', function(message) {
stopQuiz();
MessageService.alertMessage('Motstanderen din har enten gitt opp eller blitt frakoblet.');
$state.go('multiplayer.score');
});
// Disconnected. Go back to home screen.
SocketService.socket.removeAllListeners('reconnecting');
SocketService.socket.on('reconnecting', function() {
MessageService.alertMessage('Du har mistet tilkoblingen. Spillet har blitt avbrutt.');
SocketService.socket.removeAllListeners('reconnecting');
$state.go('main.front');
});
// The app was paused (closed), equals giving up.
var pauseEvent = $rootScope.$on('app:paused', function() {
QuizService.giveUpCurrent($scope.user.player);
var resumeEvent = $rootScope.$on('app:resumed', function() {
stopQuiz();
$state.go('multiplayer.score');
resumeEvent();
});
pauseEvent();
});
/**
* Give up the current quiz.
*/
$scope.giveUp = function (player) {
MessageService.confirm('Ønsker du å avbryte quizen?').then(function(result) {
if (result) {
QuizService.giveUpCurrent(player);
$state.go('multiplayer.score', {}, { reload: true });
stopQuiz();
}
});
};
/**
* Go to next question for current quiz.
*/
$scope.nextQuestion = function() {
$timeout.cancel(timeouts.stop);
$timeout.cancel(timeouts.activate);
QuizService.nextQuestion().$promise.then(function(question) {
setupQuestion(QuizService.getCurrentQuestion());
});
};
/**
* Finish quiz.
*/
$scope.finish = function() {
QuizService.finish();
$state.go('multiplayer.score');
};
/**
* Choose an alternative (aka answer current question).
*/
$scope.chooseAlternative = function(alternative) {
if (!$scope.showAlternatives || $scope.showCorrect) {
return;
}
var answerTime = Date.now() - startTime;
$scope.answer = alternative;
QuizService.answer(alternative, answerTime);
if (timeouts.stop) {
$timeout.cancel(timeouts.stop);
}
stopQuestion();
};
/**
* Set up a new question - change data and start countdown to activate question.
*/
var setupQuestion = function(question) {
$scope.showAlternatives = false;
$scope.showCorrect = false;
$scope.currentQuestion = question;
$scope.answer = {};
$scope.isLast = parseInt($scope.quiz.questionCount) == parseInt($scope.currentQuestion.questionNumber);
var prepareTime = 5000;
var newLoadBar = loadBar.cloneNode(true);
loadBar.parentNode.replaceChild(newLoadBar, loadBar);
loadBar = newLoadBar;
setAnimationDuration(loadBar, 'loadbar', prepareTime);
timeouts.activate = $timeout(activateQuestion, prepareTime);
};
/**
* A question timed out; stop and send empty answer.
*/
var questionTimeout = function() {
// Delay answering by a random delay between 0 and 500ms.
$timeout(function() {
stopQuestion();
QuizService.noAnswer($scope.currentQuestion.id);
}, Math.floor((Math.random() * 500) + 1));
};
/**
* Activate the current question: show alternatives and open answering.
*/
var activateQuestion = function() {
$scope.showAlternatives = true;
var timeToAnswer = 10000;
startTime = Date.now();
var newLoadBar = loadBar.cloneNode(true);
loadBar.parentNode.replaceChild(newLoadBar, loadBar);
loadBar = newLoadBar;
setAnimationDuration(newLoadBar, 'loadbar', timeToAnswer);
timeouts.stop = $timeout(questionTimeout, timeToAnswer);
};
/**
* Stop the current question and show the correct answer info.
*/
var stopQuestion = function() {
$scope.showCorrect = true;
stopAnimation(loadBar);
$timeout.cancel(timeouts.stop);
};
/**
* End the current quiz.
*/
var stopQuiz = function() {
SocketService.socket.removeAllListeners('gameEvent:opponentAnswer');
SocketService.socket.removeAllListeners('gameEvent:nextQuestion');
SocketService.socket.removeAllListeners('gameEvent:quizFinished');
SocketService.socket.removeAllListeners('gameEvent:opponentQuit');
SocketService.socket.removeAllListeners('reconnecting');
$timeout.cancel(timeouts.stop);
$timeout.cancel(timeouts.activate);
};
/**
* Set the animation duration for an element. Used to stop and start the
* progress bar.
*/
var setAnimationDuration = function(element, keyframes, duration) {
var animationSetting = keyframes + ' ' + duration + 'ms linear';
element.style.webkitAnimation = animationSetting;
element.style.animation = animationSetting;
}
var stopAnimation = function(element) {
element.style.webkitAnimation = 'none';
element.style.animation = 'none';
};
if (!initiated) {
initiated = true;
loadBar = document.getElementById('load-bar');
setupQuestion(QuizService.getCurrentQuestion());
}
});
I have tried with calling the responseTimer function that I have made in my controller. At the begging of the file I am calling it like this:
我试过调用我在控制器中创建的responseTimer函数。在文件的乞讨,我这样称呼它:
responseTimer(30000);
And then later I am defining it like this:
然后我将它定义为:
var responseTimer = function (time) {
responseTimer = $timeout(stopQuiz, time);
console.log('Started timer');
};
var resetResponseTimer = function () {
$timeout.cancel(responseTimer);
responseTimer(30000);
console.log("Timer reset");
};
But I get an error:
但是我收到一个错误:
TypeError: responseTimer is not a function
TypeError:responseTimer不是函数
2 个解决方案
#1
1
problem comes from a scope conflict. In your code
问题来自范围冲突。在你的代码中
// responseTimer is declared as a global function
var responseTimer = function (time) {
// as the var keyword is not specify, scope of responseTimer becomes global and not local and overrides the previous declaration
responseTimer = $timeout(stopQuiz, time);
That is why you get the error
这就是你得到错误的原因
responseTimer is not a function
To solve the problem add the var keyword before the second declaration and name your variables appropriately. A good practice is to add an action verb when naming function/object's methods, in your case triggerResponseTimer as name of your function and responseTimer as name of the variable so final porposition would be:
要解决此问题,请在第二个声明之前添加var关键字,并相应地命名变量。一个好的做法是在命名函数/对象的方法时添加一个动作动词,在你的情况下,triggerResponseTimer作为你的函数的名称,responseTimer作为变量的名称,所以最终的定位是:
var triggerResponseTimer = function (time) {
var responseTimer = $timeout(stopQuiz, time);
#2
0
You should better use $intervall: Here you will find a good sample: http://tutorials.jenkov.com/angularjs/timeout-interval.html
你应该更好地使用$ intervall:在这里你会找到一个很好的样本:http://tutorials.jenkov.com/angularjs/timeout-interval.html
Also good sample: https://docs.angularjs.org/api/ng/service/$interval
同样好的样本:https://docs.angularjs.org/api/ng/service/$interval
#1
1
problem comes from a scope conflict. In your code
问题来自范围冲突。在你的代码中
// responseTimer is declared as a global function
var responseTimer = function (time) {
// as the var keyword is not specify, scope of responseTimer becomes global and not local and overrides the previous declaration
responseTimer = $timeout(stopQuiz, time);
That is why you get the error
这就是你得到错误的原因
responseTimer is not a function
To solve the problem add the var keyword before the second declaration and name your variables appropriately. A good practice is to add an action verb when naming function/object's methods, in your case triggerResponseTimer as name of your function and responseTimer as name of the variable so final porposition would be:
要解决此问题,请在第二个声明之前添加var关键字,并相应地命名变量。一个好的做法是在命名函数/对象的方法时添加一个动作动词,在你的情况下,triggerResponseTimer作为你的函数的名称,responseTimer作为变量的名称,所以最终的定位是:
var triggerResponseTimer = function (time) {
var responseTimer = $timeout(stopQuiz, time);
#2
0
You should better use $intervall: Here you will find a good sample: http://tutorials.jenkov.com/angularjs/timeout-interval.html
你应该更好地使用$ intervall:在这里你会找到一个很好的样本:http://tutorials.jenkov.com/angularjs/timeout-interval.html
Also good sample: https://docs.angularjs.org/api/ng/service/$interval
同样好的样本:https://docs.angularjs.org/api/ng/service/$interval