在KnockoutJS中嵌套了3个级别的foreach

时间:2012-10-06 18:38:27

标签: javascript knockout.js nested-loops

我要在Knockout中管理3个级别的数据,但只有前两个才会在添加新数据时进行更新。第3级没有更新。

到目前为止,这是我的代码: http://jsfiddle.net/26medias/Zy8Wr/

有测验,每个测验都包含问题,其中包含答案。 我可以添加一个测验,我可以添加问题,但答案没有更新。

我在网上和stackoverflow上找到的所有示例仅适用于2级数据。

如何将第3级作为Observable使[+]按钮起作用?

谢谢!

2 个答案:

答案 0 :(得分:3)

对于您希望能够绑定到的每个级别的嵌套,您需要将每个级别映射到一个可观察的。

您只映射了一个可观察的问题数组。但是,您也应该在问题中映射每个答案。

scope.quizzes = ko.observableArray(
    ko.utils.arrayMap(quizzes, function(quiz) {
        return {
            name:      quiz.name,
            questions: ko.observableArray(quiz.questions) // not far enough
        };
    })
);

由于您希望能够编辑测验的名称和问答文本,因此您也应该可以观察这些属性。

scope.quizzes = ko.observableArray(
    ko.utils.arrayMap(quizzes, function(quiz) {
        return {
            name:      ko.observable(quiz.name),
            questions: ko.observableArray(
                ko.utils.arrayMap(quiz.questions, function (question) {
                    return {
                        text:    ko.observable(question.text),
                        answers: ko.observableArray(
                            ko.utils.arrayMap(question.answers, function (answer) {
                                return {
                                    text:  ko.observable(answer.text),
                                    valid: ko.observable(answer.valid)
                                };
                            })
                        )
                    };
                })
            )
        };
    })
);

这可能看起来很多,但这是你必须要做的就是能够绑定到这些对象。您可以使用mapping plugin更轻松地完成此过程,它将为您执行此映射。

scope.quizzes = ko.mapping.fromJS(quizzes);

答案 1 :(得分:1)

你的答案数组只是一个数组,它不是一个可观察的阵列。您需要将数组定义为ko.observableArray。请注意,代码段bnelow使用observableArray forall 3级数组。

var initialData = ko.observableArray([
    {
        name:    "Quiz #1",
        questions:    ko.observableArray([
            {
                text: "Question #1.1?",
                answers: ko.observableArray([
                    {
                        text:     "Yes",
                        valid:    true
                    },
                    {
                        text:     "No",
                        valid:    false
                    }
                ])
            },