【问题标题】:How to exclude certain properties from Knockoutjs toJS()如何从 Knockoutjs toJS() 中排除某些属性
【发布时间】:2013-02-05 22:45:30
【问题描述】:

我有以下型号:

var model = {
   A: 'One',
   B: 'Two',
   C: 'Three'
};

我将各种 UI 元素绑定到这些字段,效果很好。但是,我将模型转换回 JavaScript 对象,以便将任何更改保存到服务器:

var goingToServer = ko.toJS(model);

goingToServer 将包括属性 A、B 和 C。但是,假设属性 C 是一个永远不会改变的巨大数据块。我想避免将其发送回服务器。

有没有办法让toJS()在将模型转换回 JavaScript 对象时包含一组预定义的字段?

我一直在调查的一件事是Knockout Mapping plugin。它有一个名为 include 的设置,记录如下:

将视图模型转换回 JS 对象时,默认情况下 映射插件将仅包含属于您的一部分的属性 原始视图模型,除了它还将包括 剔除生成的 _destroy 属性,即使它不是您的一部分 原始对象。但是,您可以选择自定义此数组:

但是,该插件似乎无法按文档说明工作,因为 ko.mapping.toJS() 仍将包含 A、B 和 C,即使我传入 ['A', 'B']include 数组也是如此。我猜这个功能旨在包含原始模型中没有的附加字段。

有没有办法在将模型转换回 JavaScript 对象时排除某些属性,而不是做一些 hacky,例如生成对象并在发送到服务器之前手动删除我不想要的属性?

【问题讨论】:

    标签: javascript knockout.js knockout-mapping-plugin


    【解决方案1】:

    您尝试过ignore 关键字吗?它的用法与 include 类似:

    var mapping = {
        'ignore': ["propertyToIgnore", "alsoIgnoreThis"]
    }
    var viewModel = ko.mapping.toJS(data, mapping);
    

    当你对服务器数据进行原始映射时,你可以只使用忽略,然后当你将它转换回 JS 时,它根本不会出现在你的对象上。

    【讨论】:

    • 你试过了吗?由于文档没有提到在返回 JS 对象时是否可以使用忽略。
    • 是的,我刚试过。当我 ignore 字段 Notes 并调用 applyBindings 时,我立即得到一个异常,即在模型中找不到 Notes 字段。
    • 我的意思是当你转换你的视图模型以发送回你的服务器时,而不是当你映射到你的视图模型时。这有意义吗?
    • 转换是使用toJS 方法完成的,该方法没有任何参数可以忽略字段。当 Knockout 在内部将视图模型转换回 JavaScript 对象时,我正在寻找一种排除某些字段的方法。
    • 是的,文档主要集中在 fromJS 方法上,这就是我求助于查看源代码的原因!
    【解决方案2】:

    如果我们在 vm.Payment 下有一个复杂的对象模型实例,可观察引用为:

    {
        "Summary": { 
            "Count": 12,
            "PaymentAmount": 1500,
            "PaymentMethod": "Cheque",
            "PaymentDate": "2015-04-08T22:38:48.552Z",
            "AgentOid": 1208795,
            "AgentName": "Asere Ware"
        }
        //[...]
    }

    并且只需要忽略一些内部属性,那么:

    var mapping = {
        'ignore': ['Summary.PaymentMethod', 'Summary.PaymentDate'] //avoid lost some initialized values.
    };
    // map updating existing observable (Payment) under my ViewMode (vm) with source "data" JSON object.
    ko.mapping.fromJS(data, mapping, vm.Payment);

    这是 vm.Payment 内容的结果,其中仅保留了 PaymentMethod 和 PaymentDate:

    {
        "Summary": { 
            "Count": 0,
            "PaymentAmount": 0,
            "PaymentMethod": "Cheque",
            "PaymentDate": "2015-04-08T22:38:48.552Z",
            "AgentOid": undefined,
            "AgentName": undefined
        }
        //[...]
    }

    【讨论】:

      【解决方案3】:

      好的,我已经找到了一种可行的解决方案,但我希望有更好的方法。诀窍是忽略映射插件中的这些字段,然后手动将它们添加为计算字段。调用 toJS 时,计算字段永远不会出现在生成的 JavaScript 对象中。

      // Utility function to quickly generate a computed field
      ko.readonly = function (value)
      {
         return ko.computed(function ()
         {
            return value;
         });
      };
      
      // View Model
      var ViewModel = function (project)
      {
         var readonly = ['B', 'C', 'D']; // Fields I want to ignore
         var mapping = {
            'ignore': readonly //Read-only properties, we'll add these manually as computed fields
         };
      
         // Use Mapping plugin to make everything observable, except the fields above
         ko.mapping.fromJS(project, mapping, this);
      
         // Now loop through the read only array and add these fields in as computed
         for(var i = 0; i < readonly.length; i++)
         {
            var field = readonly[i];
            this[field] = ko.readonly(project[field]);
         }
      }
      

      我现在可以正常绑定到这些视图模型:

      ko.applyBindings(new ViewModel(data));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-05
        • 1970-01-01
        • 2012-11-07
        • 2021-10-13
        • 1970-01-01
        • 2012-03-21
        • 1970-01-01
        相关资源
        最近更新 更多