Ajax 敲除映射-填充可观察数组,保留项目';方法

Ajax 敲除映射-填充可观察数组,保留项目';方法,ajax,knockout.js,knockout-mapping-plugin,ko.observablearray,Ajax,Knockout.js,Knockout Mapping Plugin,Ko.observablearray,我一直面临着一个基本上如下的问题: 我有一个knockout ViewModel,它包含具有可观察属性和方法的可观察项数组 我需要从服务器中提取数据。从服务器获取数据后,这些方法需要存在。所以我创建了一个新的ViewModel,然后从服务器中更新它的值(这不起作用,生成的数组没有项) 如果我使用mapping,使用var newObj=ko.mapping.fromJS(data)创建一个新对象,则生成的数组有项,但其项没有方法。它破坏了我的装订。 我问题的症结:(只有在你点击“从服务器加载

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

  • 我有一个knockout ViewModel,它包含具有可观察属性和方法的可观察项数组
  • 我需要从服务器中提取数据。从服务器获取数据后,这些方法需要存在。所以我创建了一个新的ViewModel,然后从服务器中更新它的值(这不起作用,生成的数组没有项)
  • 如果我使用
    mapping
    ,使用
    var newObj=ko.mapping.fromJS(data)
    创建一个新对象,则生成的数组有项,但其项没有方法。它破坏了我的装订。
我问题的症结:(只有在你点击“从服务器加载数据”时它才会工作)

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


谢谢,

我稍微更改了您的代码。检查此版本的

您的代码不起作用,因为您的jsonFromServer变量不包含绑定时所需的方法,如您在问题中所述。(->元数据)

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

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),而无需在映射过程中定义自定义的create函数。

!这是一个非常完整的答案!我很感激。它就像一个符咒。然而,由于模型的复杂性,我们最终将每个属性从服务器传递到客户端。这意味着添加新属性表示代码更改,这更可能导致进一步的错误。
 --> Metadata  : which contains only simple data
 --> MetadataViewModel : which contains Metadata observableArray and its Metadata manipulator functions