2016-09-27 12 views
0

Ich habe eine Quiz-App mit einem Controller, wo ich einen Timer einrichten sollte, der für 30s zählen sollte, und dann den Quiz stoppen, wenn es in dieser Zeit keine Aktivität gibt. Wenn es in der Zwischenzeit etwas Aktivität gibt, sollte es zurückgesetzt werden und erneut zu zählen beginnen. Ich habe Web-Socket-Listener dafür eingerichtet. Wie sollte ich das Timer-Setup machen?Wie setze und setze ich die Timerfunktion?

Dies ist mein 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()); 
    } 


}); 

ich mit dem Aufruf der Funktion responseTimer versucht haben, die ich in meinem Controller gemacht haben. Am Betteln der Datei Ich rufe es wie folgt aus:

responseTimer(30000); 

Und dann später bin definieren ich es wie folgt aus:

var responseTimer = function (time) { 
    responseTimer = $timeout(stopQuiz, time); 
    console.log('Started timer'); 
    }; 

    var resetResponseTimer = function() { 
     $timeout.cancel(responseTimer); 
     responseTimer(30000); 
     console.log("Timer reset"); 
    }; 

Aber ich erhalte eine Fehlermeldung:

TypeError: responseTimer is not a function

+0

Wo Sie den Timer definieren? Auch speziell: var responseTimer = Funktion (Zeit) { responseTimer = $ timeout (stopQuiz, time); console.log ('Gestarteter Timer'); }; TwoTimes "responseTimer" – Tester

+0

welchen Timer meinst du genau? – Marco

+0

der responseTimer – Tester

Antwort

1

Problem kommt von einem Bereichskonflikt. In Ihrem 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); 

Deshalb sollten Sie den Fehler

responseTimer is not a function 

erhalten, um das Problem fügen Sie das Schlüsselwort var vor der zweiten Erklärung zu lösen und Ihre Variablen entsprechend benennen. Eine gute Praxis ist eine Aktion Verb hinzuzufügen, wenn Methoden Funktion/Objektbenennung, in Ihrem Fall triggerResponseTimer als Namen Ihrer Funktion und responseTimer als Name der Variablen so endgültig porposition wäre:

var triggerResponseTimer = function (time) { 

    var responseTimer = $timeout(stopQuiz, time); 
0

Sie sollten $ intervall besser verwenden: Hier finden Sie ein gutes Beispiel: http://tutorials.jenkov.com/angularjs/timeout-interval.html

Auch gutes Beispiel: https://docs.angularjs.org/api/ng/service/ $ Intervall

+0

Aber ich muss meine Funktion nicht wiederholt aufrufen Ich muss es aufrufen, wenn ich den Controller eingeben und dann den Timer jedes Mal zurücksetzen, wenn ich bekomme einige Antwort von Web-Socket – Marco

+0

Möchten Sie nicht den Timer Countdown auf Ihrer Seite zeigen ... dass der Benutzer die Zeit bis zum Ende sehen kann? – Tester

+0

Nein, ich verwende den Timer nur für meine eigenen Zwecke, um zu sehen, ob ich irgendeine Antwort von der Backend-API (Web-Socket) bekomme, wenn ich für 30s nichts bekomme, dann möchte ich das Quiz stoppen – Marco

Verwandte Themen