Knockout JS使用javascript类型从服务器数据初始化可观察数组

Sim*_*Fox 8 javascript asp.net-mvc asp.net-mvc-3 knockout.js

我正在寻找从一些服务器数据(ViewBag)初始化一个淘汰可观察数组的最佳方法,我希望数组内容是我定义的javascript类型.没有JS类型的要求我可以使用:

materialVarieties: ko.observableArray(@Html.Raw(Json.Encode(ViewBag.Materials)))
Run Code Online (Sandbox Code Playgroud)

但我也有一个我想要使用的材料JS类型,所以我可以有一些额外的ViewModel特定的属性和功能,即:

var material = function(id, name) {
    this.id = id;
    this.name = name;
    this.selected = ko.observable(false);

    this.select = function()
     {
        jQuery.each(processViewModel.materials(), function(index, item)
        {
            item.selected(false);
        });
        this.selected(true);
      }
}
Run Code Online (Sandbox Code Playgroud)

然后所需的初始化变为:

materialVarieties: ko.observableArray([new material(1, "Apricot"), .....
Run Code Online (Sandbox Code Playgroud)

目前我从ViewBag数据构建一个字符串,然后将其渲染为初始化器,如下所示:

@{ var items = string.Join(",",
                ((IEnumerable<MaterialVariety>) ViewBag.Materials)
                            .Select(m => string.Format("new material({0}, {1})",
                                      Json.Encode(m.Id), Json.Encode(m.Name)))); }

var processViewModel = {
    material: ko.observableArray([@Html.Raw(items)])
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有比这更清洁的方式string.Join.我可以把它包装在一个助手里.你是做什么?

RP *_*yer 15

我通常首先序列化数组,然后在将它放入视图模型时映射它.就像:

var originalVarieties = @Html.Raw(Json.Encode(ViewBag.Materials))

var processViewModel = {
   materialVarieties: ko.observableArray(ko.utils.arrayMap(originalVarieties, function(variety) {
      return new material(variety.id, variety.name);
   }))
}
Run Code Online (Sandbox Code Playgroud)

在客户端需要少量的额外处理,但似乎比构建字符串更清晰.

  • 是的,ko.utils.arrayMap没有什么特别之处.非常简单的代码.jQuery map也会这样做. (2认同)