Почему observableArray не наблюдается в Knockout JS?
Я новичок в программировании (особенно в JS и даже больше в KO), и я пытаюсь придумать интерактивный тест, предназначенный для использования в классе старшеклассниками. Благодаря этой статье (которая предоставила инструкции и код, который я использовал в качестве основы, пытаясь адаптировать его под свои нужды) и помощи некоторых хороших людей здесь, я теперь придумал что-то похожее на это:
Все хорошо, потому что это функционально. Но...:p Теперь я хотел бы добавить массив observableArray, в который я бы нажимал () все выбранные ответы каждый раз, когда пользователь щелкает один из них, чтобы в конце я мог сравнить selectedAnswers(). Length с questions(). Length и, если они одинаковые, я бы сделал (еще не включенным в код) видимым.
Я объявил свой массив в конструкторе QuizViewModel следующим образом (поскольку он касается всего теста, поэтому я думаю, что он должен идти):
var selectedAnswers = ko.observableArray();
И затем мне нужно каждый раз вставлять в него свойство selectedAnswer из конструктора Вопросов. И вот в чем проблема... Вот часть моего сценария:
//Construction
$.each(quizName.controls, function(index, question) {
quiz.questions.push(new Question(index + 1, question));
quiz.selectedAnswers().push(question.selectedAnswer);
});
Это заполняет массив selectedAnswers (), но он заполняется только неопределенными значениями, которые 1) не меняются, даже когда я щелкаю по ответу (undefined не заменяется нажатыми selectedAnswer...) и selectedAnswers(). Длина уже равна к общему количеству вопросов, что означает, что сравнение, которое я хотел сделать, не будет работать...
Должна быть какая-то фундаментальная логика нокаута, которую я здесь не понимаю (или это логика JS, которая определенно, похоже, ускользает от меня!) Любые мысли по этому вопросу будут с благодарностью!
1 ответ
Используйте вычисленный для вашего списка "выбранных ответов".
function Question(config) {
this.text = text;
this.questionText = config.questionText;
this.answers = config.answers;
this.selectedAnswer = ko.observable();
}
function QuizViewModel(quizName) {
this.questions = ko.observableArray(
ko.utils.arrayMap(quizName.controls, function (control) {
return new Question(control);
})
);
this.selectedAnswers = ko.computed(function () {
return ko.utils.arrayMap(this.questions(), function (q) {
return q.selectedAnswer();
}
});
}
Нет необходимости поддерживать отдельный стек (то есть наблюдаемый массив) ответов, когда ответ уже является свойством самого вопроса.