为什么 currentQuestion 未定义?

Why is currentQuestion undefined?

我只想显示当前的问题选项。我已将 ViewModel 中的 currentQuestion 设置为数组中的第一个元素。 然而它是未定义的。 我安装了 knockout context chrome 插件,所有其他变量似乎都设置正确。我不知道为什么 currentQuestion 的值为 undefined。 谢谢

<div id="quiz-container">
 <form action="">
    <div data-bind="with: currentQuestion">
        <h3 data-bind="text: question"></h3>

        <div data-bind="foreach: choices">

            <input type="radio" data-bind="checkedValue: $data, checked: $parent.selectedAnswer" />
            <span data-bind="text: $data">choice</span>

        </div>
        <div>
            <button data-bind="click: $parent.previousQuestion">Previous</button>
            <button data-bind="click: $parent.nextQuestion">Next</button>
        </div>
    </div>
    <div><input type="submit"/></div>
</form>
</div>
<script src="js/jQuery.js"></script>

function Question( data ) {
var self = this;
self.question = data.question;
self.choices = ko.observableArray( [] );
data.choices.forEach( function ( c ) {
    self.choices.push( c );
} );
self.answer = data.answer;
};

function QuizViewModel() {

var self = this;

self.questionList = ko.observableArray( [] );

// Load initial state from server, convert it to Question instances, then populate self.questions
$.getJSON( "js/questions.json", function ( allData ) {
    var mappedQuestions = $.map( allData, function ( item ) {
        return new Question( item )
    } );
    self.questionList( mappedQuestions );
} );

self.currentQuestion = ko.observable(self.questionList()[0]);

this.previousQuestion = function () {
    var index = self.questionList().indexOf( self.currentQuestion );
    self.currentQuestion( self.questionList()[index - 1] );
};

this.nextQuestion = function () {
    var index = self.questionList().indexOf( self.currentQuestion );
    self.currentQuestion( self.questionList()[index + 1] );
};

};

ko.applyBindings( new QuizViewModel() );

这是因为它是在实例化 QuizViewModel 时设置的,而问题是异步获取的。相反,只需创建一个可观察对象,并在异步调用时设置它 returns:

$.getJSON( "js/questions.json", function ( allData ) {
    var mappedQuestions = $.map( allData, function ( item ) {
        return new Question( item )
    } );
    self.questionList( mappedQuestions );

    //set current question when the async call returns
    self.currentQuestion(self.questionList()[0]);
} );

//initialise as observable
self.currentQuestion = ko.observable();