Knockout.js 通过索引从ObservalArray获取对象

Knockout.js 通过索引从ObservalArray获取对象,knockout.js,Knockout.js,我正在用Knockoutjs设计一个测验。我想一次只显示一个问题。我在考虑一个全局计数变量,每次回答一个问题时,该变量加上1。然而,我似乎找不到一种方法,一次只能问一个问题。 我该如何最好地处理这个问题?我是个新手。我试过提问()[number],但似乎不起作用 谢谢 JS HTML }Jsfiddle很有趣,所以我不能在那里发布代码,但很简单:你就快到了!这里有一点推力 首先,除非必要,否则调用标记中的方法并不是很好的做法,并且为函数提供参数可能意味着您可以为此使用可观察的方法。在这种情况下:

我正在用Knockoutjs设计一个测验。我想一次只显示一个问题。我在考虑一个全局计数变量,每次回答一个问题时,该变量加上1。然而,我似乎找不到一种方法,一次只能问一个问题。 我该如何最好地处理这个问题?我是个新手。我试过提问()[number],但似乎不起作用

谢谢

JS

HTML


}Jsfiddle很有趣,所以我不能在那里发布代码,但很简单:你就快到了!这里有一点推力

首先,除非必要,否则调用标记中的方法并不是很好的做法,并且为函数提供参数可能意味着您可以为此使用可观察的方法。在这种情况下:

<div data-bind="foreach: filteredQuestions">
<ul class="list-container"  data-bind="foreach: answers">
    <li class="list-item">
         <a class="list-item-content" href="#" data-bind="text: answer"></a>
    </li>

</ul>
<button data-bind="click: $parent.nextQuestion">Next question</button>
</div>
如果您注意代码,我只返回一个数组,其中只有一个问题,Id与
currentQuestionId
变量设置的相同。这是一种方法,尽管有很多:另一种好的方法有一个可观察的问题,叫做
selectedQuestion
,哪个值是第一个问题;然后在标记中使用数据绑定
和:selectedQuestion
。但是,让我们继续讨论这个问题,您能猜到$parent.nextQuestion的作用吗

self.nextQuestion = function() {
    var currentQuestionId = self.currentQuestionId();
    self.currentQuestionId(currentQuestionId + 1);
}
首先,我们使用
$parent
关键字来浏览实际的范围父项,因为由于
foreach
语句,我们处于子
问题中。由于您的需求,此功能可以正常工作,但可能存在一些缺陷(在上一个问题中,我们该怎么办?如果id的数量没有增加怎么办?)。这时,另一种方法可能更有用,在这种情况下,您可能会遇到如下情况:

self.nextQuestion = function(question) {
    var index = self.questions().indexOf(question);
    self.selectedQuestion(self.questions()[index + 1]);
}
最后一种方法的优点是什么?嗯,反问很容易

self.backQuestion = function(question) {
    var index = self.questions().indexOf(question);
    self.selectedQuestion(self.questions()[index - 1]);
}
(您显然需要检查IndexOutOfBounds类型错误)。在最后一种方法中,不要忘记,因为我们在一个上下文切换元素(如
foreach
)中,所以我们将当前问题作为一个参数接收。希望这有帮助。

是一个有效的解决方案

代码使用插件简化视图模型的创建。
“questionIndex”和“currentQuestion”观察值跟踪当前问题

function AnswerViewModel(){
  var self = this;
  ko.mapping.fromJS(data, {}, self);

  this.questionIndex = ko.observable(0);
  this.currentQuestion = ko.computed(function(){
     return self.questions()[self.questionIndex()];
  });

this.nextQuestion = function(){
  var questionIndex = self.questionIndex();
  if(self.questions().length - 1 > questionIndex){
    self.questionIndex(questionIndex + 1);
  }
};

this.prevQuestion = function(){
  var questionIndex = self.questionIndex();
  if(questionIndex > 0){
    self.questionIndex(questionIndex - 1);
  }
};

this.checkAnswer = function(item, event){
  $(event.currentTarget).css("background", item.correct() ? "green" : "red");
};  
}
标记:

<!-- ko with: currentQuestion -->
<h3 data-bind="text: question"></h3>
<ul class="list-container" data-bind="foreach: answers">
  <li class="list-item">
     <a class="list-item-content" href="#" data-bind="text: answer, click:$root.checkAnswer"></a>
</li>
</ul>
<!-- /ko -->


这里我使用虚拟元素
来介绍所需的上下文。

感谢您的回复!我真的很感谢你花时间解释清楚这一点。我试过了,可惜什么也没显示出来。还有什么我做错了吗?我在代码中犯了几个错误,它是self.questions()
,而不是question,在下一个问题上,你需要一个parseInt,比如'self.currentQuestionId(parseInt(currentQuestionId,10)+1);`;这是密码笔-谢谢,我来看看。
self.nextQuestion = function(question) {
    var index = self.questions().indexOf(question);
    self.selectedQuestion(self.questions()[index + 1]);
}
self.backQuestion = function(question) {
    var index = self.questions().indexOf(question);
    self.selectedQuestion(self.questions()[index - 1]);
}
function AnswerViewModel(){
  var self = this;
  ko.mapping.fromJS(data, {}, self);

  this.questionIndex = ko.observable(0);
  this.currentQuestion = ko.computed(function(){
     return self.questions()[self.questionIndex()];
  });

this.nextQuestion = function(){
  var questionIndex = self.questionIndex();
  if(self.questions().length - 1 > questionIndex){
    self.questionIndex(questionIndex + 1);
  }
};

this.prevQuestion = function(){
  var questionIndex = self.questionIndex();
  if(questionIndex > 0){
    self.questionIndex(questionIndex - 1);
  }
};

this.checkAnswer = function(item, event){
  $(event.currentTarget).css("background", item.correct() ? "green" : "red");
};  
}
<!-- ko with: currentQuestion -->
<h3 data-bind="text: question"></h3>
<ul class="list-container" data-bind="foreach: answers">
  <li class="list-item">
     <a class="list-item-content" href="#" data-bind="text: answer, click:$root.checkAnswer"></a>
</li>
</ul>
<!-- /ko -->