首页 > 解决方案 > How to generate new object while using the same methods

问题描述

The project I am working on originally consisted of a single quiz that asked five questions and at the end it will tell you your score and that is it. I am learning more about the MVC model and so it was built using that model.

Now I want to add new features to the quiz app such as if you get a score greater than three the final page with a score with have a button that says "level 2" as in the image below and when you click on it it takes you to the next level with a new set of questions from another object:

level

If you score less than three you get a button that will say "try again" and the quiz restarts. If you move on to the next level I want the score to be kept and the same process will take place until you reach the third level.

The issue I am having is trying to figure out how to reuse the same code to repopulate the page with a new set of questions for the next level and to keep track of the score. I tried to create a new method called nextLevel that when you click the level two button the quiz will repopulate with the new questions but that is not happening. Any help or guidance would be appreciated.

Here is my index.html:

<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Capstone</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <div class="grid">
        <div id="quiz">
            <h1>JerZey's</h1>
            <hr style="margin-bottom: 20px">

            <p id="question"></p>

            <div class="buttons">
                <button id="btn0"><span id="choice0"></span></button>
                <button id="btn1"><span id="choice1"></span></button>
                <button id="btn2"><span id="choice2"></span></button>
                <button id="btn3"><span id="choice3"></span></button>
            </div>

           <div id="btn5">

           </div>

            <hr style="margin-top: 50px">
            <footer>
                <p id="progress">Question x of y</p>
            </footer>
        </div>
    </div>

<script src="quiz.js"></script>
<script src="question.js"></script>
<script src="app.js"></script>
</body>
</html>

Here is my model(question.js):

function Quiz(questions) {
    this.score = 0;
    this.questions = questions;
    this.questionIndex = 0;
}

Quiz.prototype.getQuestionIndex = function() {
    return this.questions[this.questionIndex];
}

Quiz.prototype.guess = function(answer) {
    if(this.getQuestionIndex().isCorrectAnswer(answer)) {
        this.score++;
    }

    this.questionIndex++;
}

Quiz.prototype.isEnded = function() {
    return this.questionIndex === this.questions.length;
}

Controller (quiz.js):

function Quiz(questions) {
    this.score = 0;
    this.questions = questions;
    this.questionIndex = 0;
}

Quiz.prototype.getQuestionIndex = function() {
    return this.questions[this.questionIndex];
}

Quiz.prototype.guess = function(answer) {
    if(this.getQuestionIndex().isCorrectAnswer(answer)) {
        this.score++;
    }

    this.questionIndex++;
}

Quiz.prototype.isEnded = function() {
    return this.questionIndex === this.questions.length;
}

Views(app.js):

function populate() {
    if(quiz.isEnded()) {
        showScores();
    }
    else {
        // show question
        var element = document.getElementById("question");
        element.innerHTML = quiz.getQuestionIndex().text;

        // show options
        var choices = quiz.getQuestionIndex().choices;
        for(var i = 0; i < choices.length; i++) {
            var element = document.getElementById("choice" + i);
            element.innerHTML = choices[i];
            guess("btn" + i, choices[i]);
        }

        showProgress();
    }
};

function guess(id, guess) {
    var button = document.getElementById(id);
    button.onclick = function() {
        quiz.guess(guess);
        populate();
    }
};


function showProgress() {
    var currentQuestionNumber = quiz.questionIndex + 1;
    var element = document.getElementById("progress");
    element.innerHTML = "Question " + currentQuestionNumber + " of " + quiz.questions.length;
};

function showScores() { 



    if(quiz.score < 3){
  var gameOverHTML = "<h1>Level 1 Complete</h1>";
    gameOverHTML += "<h2 id='score'> Your scores: " + quiz.score + "</h2><button onClick='refreshPage()' type='button'>Try Again</button>";
    var element = document.getElementById("quiz");
    element.innerHTML = gameOverHTML;
  }else{
    var gameOverHTML = "<h1>Level 1 Complete</h1>";
    gameOverHTML += "<h2 id='score'> Your scores: " + quiz.score + "</h2><button type='button' onClick='nextLevel()'>Level 2</button>";
    var element = document.getElementById("quiz");
    element.innerHTML = gameOverHTML;
  }


};

function refreshPage() {
location.reload();
};

function nextLevel(){ //This is where I am stuck at and am not sure if I even need it or if I am going about it the wrong way
var quiz = new Quiz(questions2);
populate();
};


// find a way to show countdown on screen
// setInterval(showScores, 5000);

// create questions
var questions = [
    new Question("What two teams have been active since 1920?", ["New York Giants and Dallas Cowboys", "Denver Broncos and Oakland Raiders","Arizona Cardinals and Chicago Bears", "Green Bay Packers and Detroit Lions "], "Arizona Cardinals and Chicago Bears"),
    new Question("What team has 216 games played?", ["Houston Texans", "Los Angeles Chargers", "Miami Dolphins", "Washington Redskins"], "Houston Texans"),
    new Question("What's the correct number of the Oakland Raiders Post-season record of wins?", ["17", "34","100", "25"], "25"),
    new Question("Which team has the colors yellow and green?", ["49ers", "Rams", "Packers", "Vikings"], "Packers"),
    new Question("What was Kansas City Chiefs regular season record ties?", ["67", "12", "10", "30"], "12")
];

var questions2 = [
    new Question("Which team hired their 1st professional cheerleading squad?", ["Dallas Cowboys", "San Francisco 49ers","Tampa Bay Buccaneers", "Chicago Bears "], "Dallas Cowboys"),
    new Question("What team won the first final in January 1967?", ["Houston Texans", "Los Angeles Chargers", "Miami Dolphins", "Greenbay Packers"], "Greenbay Packers"),
    new Question("Who won the most superbowls in history?", ["Steelers", "Redskins","Lions", "Seahawks"], "Steelers"),
    new Question("The curse of 10 which NFL team has only scored 10 points in 3 different superbowls?", ["Raiders", "Rams", "Broncos", "Vikings"], "Broncos"),
    new Question("How many rings does Tom Brady have?", ["4", "1", "3", "5"], "5")
];

var questions3 = [
    new Question("What were Nfl players required to wear in games for the 1st time in 1943?", ["Knee pads", "Bandanas","Helmets", "Raider Jerseys "], "Helmets"),
    new Question("What was the Nfl's sports caster Madden's first name ?", ["Derek", "John", "Anthony", "Bob"], "John"),
    new Question("How many years do players have to be retired to be eligible for the Hall of Fame", ["10", "2","7", "5"], "5"),
    new Question("Where were the Rams originally franchised before they moved to Los Angeles?", ["Cleveland", "Atlanta", "Detroit", "New York"], "Cleveland"),
    new Question("Which Nfl team features a helmet decal only on one side?", ["Eagles", "Saints", "Jaguars", "Steelers"], "Steelers")
];
// create quiz
var quiz = new Quiz(questions);

// display quiz
populate();

Here is what the quiz looks like when you lose:

second

Here is what it looks like in the beginning:

last

标签: javascriptoopmodel-view-controller

解决方案


有趣的练习。为了尽可能地遵守 MVC,我将按如下方式实现它。

您实例化您的模型和视图,并将它们传递给控制器​​,在您的主应用程序部分,然后让控制器“控制”视图和模型。

我省略了难度级别的处理,但应该很清楚它适合的地方。

模型.js

function Question(text, choices, answer) {
    this.text  = text;
    this.choices = choices;
    this.answer = answer;
}

Question.prototype.hasAnswer = function (answer) {
    return this.answer === answer;
};

function Model(questions) {
    this.questions = questions;
    this.questionIndex = 0;
    this.score = 0;
}

Model.prototype.nextQuestion = function () {
    if (this.questionIndex < this.questions.length) 
        return this.questions[this.questionIndex];
    return null;
};

Model.prototype.checkAnswer = function (choice) {
    if (this.questions[this.questionIndex].hasAnswer(choice))
        this.score++;
    this.questionIndex++;
};

Model.prototype.reset = function () {
    this.questionIndex = 0;
    this.score = 0;
};

控制器.js

function Controller(doc, model) {
    this.doc = doc;
    this.model = model;
}

Controller.prototype.initialize = function () {
    this.next();
};

Controller.prototype.next = function () {
    const that = this;
    const question = this.model.nextQuestion();
    if (question == null) {
        this.showScore();
        return;
    }
    const questionSection = this.doc.querySelector("#question");
    questionSection.innerHTML = question.text;
    const choicesSection = this.doc.querySelector("#choices");
    choicesSection.innerHTML = "";
    for (let choice of question.choices) {
        const choiceButton = this.doc.createElement("button");
        choiceButton.innerHTML = choice;
        choiceButton.addEventListener("click", function (e) {
            that.model.checkAnswer(choice);
            that.next();
        });
        choicesSection.append(choiceButton);
    }
};

Controller.prototype.showScore = function () {
    const that = this;
    this.clear();
    const scoreSection = this.doc.querySelector("#score");
    scoreSection.innerHTML = "Score: " + this.model.score;
    const tryAgainButton = this.doc.createElement("button");
    tryAgainButton.innerHTML = "Try again";
    tryAgainButton.addEventListener("click", function (e) {
        scoreSection.innerHTML = "";
        that.model.reset();
        that.next();
    });
    scoreSection.append(this.doc.createElement("p"));
    scoreSection.append(tryAgainButton);
};

Controller.prototype.clear = function () {
    const questionSection = this.doc.querySelector("#question");
    questionSection.innerHTML = "";
    const choicesSection = this.doc.querySelector("#choices");
    choicesSection.innerHTML = "";
};

Index.html(查看)

<!DOCTYPE html>
<html>
    <head>
    <title>Quizaaaaaaaaaaaaaaaaaaaaa</title>
    <script type="text/javascript" src="model.js"></script>
    <script type="text/javascript" src="controller.js"></script>
    <script type="text/javascript">
        window.addEventListener("load", function (e) {
        const questions = [
            new Question("Question A", ["A", "B", "C", "D"], "A"),
            new Question("Question B", ["A", "B", "C", "D"], "B"),
            new Question("Question C", ["A", "B", "C", "D"], "C"),
            new Question("Question D", ["A", "B", "C", "D"], "D")
        ];
        const model = new Model(questions);
        const controller = new Controller(document, model);
        controller.initialize();
        });
    </script>
    </head>
    <body>
    <div id="question"></div>
    <div id="choices"></div>
    <div id="score"></div>
    </body>
</html>

推荐阅读