1

我一直面临一个基本上如下的问题:

  • 我有一个淘汰视图模型,其中包含具有可观察属性和方法的可观察项目数组。
  • 我需要从服务器中提取数据。从服务器获取数据后,方法需要存在。所以我创建了一个新的 ViewModel,然后根据来自服务器的内容更新它的值。(这不起作用,生成的数组没有项目)
  • 如果我使用生成的 Array创建mapping一个新对象,它有项目,但它的项目没有方法。它破坏了我的绑定。var newObj = ko.mapping.fromJS(data)

我的问题的小提琴:http: //jsfiddle.net/claykaboom/R823a/3/(它可以在您单击“从服务器加载数据”时使用)

最后一个问题是:在不使加载过程过于繁琐的情况下,将项目放在最终数组中的最佳方法是什么,例如遍历每个项目并填充项目的属性以保留先前声明的方法?

谢谢,

4

1 回答 1

2

我稍微改变了你的代码。检查此版本的JSFiddle

 var jsonFromServer = '{"ModuleId":1,"Metadatas":[{"Id":1,"MinValue":null,"MaxValue":null,"FieldName":"Teste","SelectedType":"String","SelectedOptionType":null,"IsRequired":true,"Options":[]}]}';

您的代码不起作用,因为您的 jsonFromServer 变量不包含我们在绑定时需要的方法,就像您在问题中描述的那样。(--> 元数据)

所以我们需要在映射过程中为 Metadata 对象定义一个自定义创建函数,如下所示:

var mapping = {
    'Metadatas': {
        create: function(options) {
            var newMetaData = new MetadataViewModel(options.parent);

            newMetaData.Id(options.data.id);
            newMetaData.FieldName(options.data.FieldName);
            newMetaData.SelectedType(options.data.SelectedType);
            newMetaData.SelectedOptionType(options.data.SelectedOptionType);
            newMetaData.IsRequired(options.data.IsRequired);
            newMetaData.Options(options.data.Options);

            // You can get current viewModel instance via options.parent
            // console.log(options.parent);

            return newMetaData;
        }
    }
}

然后我将您的加载功能更改为:

self.LoadDataFromServer = function() {

    var jsonFromServer = '{"ModuleId":1,"Metadatas":[{"Id":1,"MinValue":null,"MaxValue":null,"FieldName":"Teste","SelectedType":"String","SelectedOptionType":null,"IsRequired":true,"Options":[]}]}';

    ko.mapping.fromJSON(jsonFromServer, mapping, self);
}

您不必声明新的 viewModel 并再次调用 ko.applyBindings。将更新后的映射分配给当前 viewModel 就足够了。有关更多信息,请查看此链接。注意自定义对象构造部分。

最后一个问题是:在不使加载过程过于繁琐的情况下,将项目放在最终数组中的最佳方法是什么,例如遍历每个项目并填充项目的属性以保留先前声明的方法?

据我所知,没有简单的方法可以通过您的对象实现来做到这一点。你的对象并不简单。它们同时包含数据和函数。因此,您需要为它们定义自定义创建功能。但是,如果您能够像下面这样将其分开,那么您不必自定义对象构造。

例如,将 MetadataViewModel 分离到两个不同的对象:

 --> Metadata  : which contains only simple data
 --> MetadataViewModel : which contains Metadata observableArray and its Metadata manipulator functions

使用此结构,您可以调用 ko.mapping.fromJSON(newMetaDataArray , {} , MetadataViewModelInstance.MetadataArray) 而无需在映射过程中定义自定义创建函数。

于 2012-08-06T19:53:44.083 回答