KnockoutJS中的后期可观察数组绑定

时间:2012-07-28 14:00:01

标签: javascript knockout.js javascriptserializer

我的MVC剃刀视图呈现此标记:

function existingNamingsViewModel() {
            var self = this;
            var initialData = @Html.Raw(new JavaScriptSerializer().Serialize(Model));
            self.ExistingNamings = ko.observableArray(initialData);
        }
        ko.applyBindings(new existingNamingsViewModel(), document.getElementById("namings-control"));

进入正确的JS序列化代码,将initialData变量初始化为:

var initialData = [{"TypeName":"Orders","NameBlocks":["{intInc_G}","/","{intInc_D}","/02/-","{yy}"],"ParamBlocks":["2296","","1","",""]}];

应用ko绑定后生成的html采用可编辑网格的形式: enter image description here

每当用户更改这些输入字段中的数据时,我都需要knockoutJS自动更新视图模型。但由于视图模型是从简单的JSON对象初始化的,因此NameBlocksParamBlocks不是ko.observableArray。我需要它们。我该如何实现这一目标?

P.S。一个想法是进行更复杂的初始化,其中razor仅序列化Name / ParamBlocks数组,并且通过javascript代码手动填充ExistingNamings数组,创建具有{{的自定义命名类对象1}} / Name包含在ParamBlocks中。但这是唯一的方法吗?

1 个答案:

答案 0 :(得分:1)

有一个mapping plug-in可供您使用,但您可能需要更改数据的传送方式。

映射插件提供了一个将JSON对象映射到视图模型的函数:

var viewModel = ko.mapping.fromJS(data);

但请注意,在文档中(链接到上面),JSON对象中的所有属性都被命名。

您在示例中提供的initialData包含的数组只是值的集合,而不是命名值的集合。

此外,initialData是一个包含单个对象的数组。如果这种情况总是期望单个对象,那么这个解决方案就更容易了。

假设您能够以下列格式投放initialData

var initialData = {
    "TypeName":"Orders",
    "NameBlocks": [
        {"block":"{intInc_G}"},
        {"block":"/"},
        {"block":"{intInc_D}"},
        {"block":"/02/-"},
        {"block":"{yy}"}
    ],
    "ParamBlocks":[
        {"block":"2296"},
        {"block":""},
        {"block":"1"},
        {"block":""},
        {"block":""}
    ]
};

然后创建视图模型将如下所示:

var viewModel = ko.mapping.fromJS(initialData);

$(function() {
   ko.applyBindings(viewModel); 
});

这是我设置的小提琴,所以你可以看到这个:http://jsfiddle.net/jimmym715/qUjLQ/

希望您的解决方案就像一些数据格式更改和映射插件的使用一样简单。

无论如何,映射插件应该向您发送正确的方向。