【问题标题】:Map nested JSON data to Knockout observableArray将嵌套的 JSON 数据映射到 Knockout observableArray
【发布时间】:2012-09-24 17:18:33
【问题描述】:

我们在 Knockout 中有一个 observableArray,其中包含几个 JSON 对象。 在每个 JSON 对象下,我们都有一个需要可观察的嵌套数组。

Knockout 无法在 observableArray 中观察嵌套在每个 JSON 对象中的数组。

是否可以映射已经嵌套在 observableArray 中的数组?

这是 observableArray 中一个 JSON 对象的示例。

注意:我们需要使“attributeValues”数组可观察。

{
    "attribute": {
        "id": 6,
        "name": "Some attribute name",
        "typeID": 5
    },
    "type": {
        "id": 5,
        "typeName": "list"
    },
    "attributeValues": [{
        "id": 10,
        "attributeID": 6,
        "value": "Some attribute value",
        "chosen": false
    }, {
        "id": 11,
        "attributeID": 6,
        "value": "Another attribute value",
        "chosen": false
    }, {
        "id": 12,
        "attributeID": 6,
        "value": "Third attribute value",
        "chosen": false
    }]
}

这是我们现在使用的代码:

$.ajax({
    type: 'GET',
    url: '/JsonService',
    success: function (data) {
        avm.attributes(data.allAttributes);
    },
    dataType: 'json',
    traditional: true
});

function attributeViewModel() {
    var self = this;

    self.attributes = ko.observableArray([]);
}

var avm = new attributeViewModel();
ko.applyBindings(avm);

【问题讨论】:

    标签: javascript knockout.js


    【解决方案1】:

    一种解决方案是再定义一个构造函数来包装 attributes 数组的每一项。在此函数中,您可以将 attributeValues 数组定义为可观察的,如下例所示:

    function AttributeValueViewModel (data) {
        var self = this;
        self.attribute = ko.observable(data.attribute);
        self.type = ko.observable(data.type);
        self.attributeValues = ko.observableArray(data.attributeValues);
    }
    
    function attributeViewModel() {
        var self = this;
        self.attributes = ko.observableArray([]);
        self.addList = function (list) {
            ko.utils.arrayForEach(list, function(item) {
                self.attributes.push(new AttributeValueViewModel(item));
            });
        };
    }
    
    var avm = new attributeViewModel();
    ko.applyBindings(avm);
    $.getJSON('url', function (list) { avm.addList(list); });
    

    【讨论】:

    • 它不工作。在 addList() arrayForEach 循环之后,我输入: console.log(self.attributes());并得到:[{},{},{},{},{},{}]。我还验证了参数“item”中的数据并得到了正确的数据,但是在循环之后它没有显示任何数据。
    • 以下小提琴包含一个工作示例:jsfiddle.net/ELMkS/2。可以看到数组项不为空。
    • 这太奇怪了。这是我的代码/输出:pastebin.com/NNYj1bbW - 唯一的区别是您在 ko.applyBindings(avm) 下方调用 avm.addList() 但我在 AJAX 函数中将其称为“成功”。我什至尝试将 AJAX 移到 ko.applyBindings(avm) 下方,但没有成功。
    • 但是这样做,您删除了嵌套数组中的可观察对象(您的问题的目标!!)。问题在于您获取对象的 JSON 表示的方式。当使用带有 observables 的对象时,你不能再使用 JSON.stringify 而是 ko.toJSON (一个处理 observable 的特殊版本)。这就是为什么你的数组看起来是空的。
    • KO中的常见错误:在绑定表达式中使用observable时,必须使用函数调用来调用它们。这是您的示例的有效小提琴:jsfiddle.net/ELMkS/3
    猜你喜欢
    • 2012-06-24
    • 2012-04-14
    • 2015-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 2020-03-19
    相关资源
    最近更新 更多