代码之家  ›  专栏  ›  技术社区  ›  ClayKaboom

淘汰映射-填充保持项目方法的可观测阵列

  •  1
  • ClayKaboom  · 技术社区  · 12 年前

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

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

    我问题的关键: http://jsfiddle.net/claykaboom/R823a/3/ (只要你点击,它就会起作用 “从服务器加载数据” )

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

    谢谢

    1 回复  |  直到 12 年前
        1
  •  2
  •   Luffy    12 年前

    我稍微更改了你的代码。检查此版本的 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。将更新后的映射分配给当前视图模型就足够了。有关详细信息,请查看 this link .注意自定义对象构造部分。

    最后一个问题是:在期末考试中有项目的最佳方式是什么 阵列,而不会使加载过程过于繁琐,例如 遍历每个项并填充项的属性,以便 保留之前声明的方法?

    据我所知,用你的对象实现并没有简单的方法。你的物品并不简单。它们同时包含数据和函数。因此,您需要为它们定义自定义创建功能。但如果你能像下面这样将其分离,那么你就不必自定义对象构造了。

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

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

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