Почему observableArray не наблюдается в Knockout JS?

Я новичок в программировании (особенно в JS и даже больше в KO), и я пытаюсь придумать интерактивный тест, предназначенный для использования в классе старшеклассниками. Благодаря этой статье (которая предоставила инструкции и код, который я использовал в качестве основы, пытаясь адаптировать его под свои нужды) и помощи некоторых хороших людей здесь, я теперь придумал что-то похожее на это:

http://jsfiddle.net/sNJm3/2/

Все хорошо, потому что это функционально. Но...: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();
        }
    });
}

Нет необходимости поддерживать отдельный стек (то есть наблюдаемый массив) ответов, когда ответ уже является свойством самого вопроса.

Другие вопросы по тегам