2015-03-13 91 views
0

我只想显示当前的问题选项。我已将ViewModel中的currentQuestion设置为数组中的第一个元素。 但它是未定义的。 我安装了淘汰赛上下文chrome插件,并且所有其他变量似乎设置正确。我不知道为什么currentQuestion具有未定义的值。 感谢为什么currentQuestion未定义?

<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()); 
+0

检查self.questionList()[index-1]是否有正确的值? – 2015-03-13 11:50:29

回答

1

这是因为它被设置在QuizViewModel被实例化的时间,而问题是异步了。相反,只需创建一个observable,并在异步调用返回时设置它:

$.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(); 
+0

这是第一次加载的问题..但是当你下一个/上一个时,它应该工作 – 2015-03-13 11:51:38

+0

如果它没有正确启动 - indexOf调用总是返回-1,所以以前不会工作(至少直到你点击下一步),但接下来会好的。无论哪种方式 - 在加载问题后需要正确初始化。您无法将其初始化为尚未填充数组的成员。 – 2015-03-13 11:53:35

+0

感谢您的快速回复!这就说得通了。现在它被设置为第一个问题对象。然而绑定似乎不起作用,所以没有显示。如果我用'questionList()[0]'替换'with:currentQuestion',它确实显示正确。有什么建议么? – paul 2015-03-13 12:28:52