【问题标题】:Knockout.js Adding a Property to Child ElementsKnockout.js 向子元素添加属性
【发布时间】:2017-04-17 06:12:12
【问题描述】:

我的代码没有在由 knockout.mapping.fromJS 映射的淘汰视图模型的子元素下创建新属性。

我有:

//model from Entity Framework
console.log(ko.mapping.toJSON(model));
var viewModel = ko.mapping.fromJS(model, mappingOption);
ko.applyBindings(viewModel);
console.log(ko.mapping.toJSON(viewModel));

第一个 console.log 输出:

{
  "Id": 0,
  "CurrentUser": {
    "BoardIds": [
      {
        "Id": 0
      }
    ],
    "Id": 1,
    "UserName": "foo",
    "IsOnline": true
  },
  "Boards": []
}

然后mappingOption就是:

var mappingOption = {
    create: function (options) {
        var modelBase = ko.mapping.fromJS(options.data);

        modelBase.CurrentUser.UserName = ko.observable(model.CurrentUser.UserName).extend({ rateLimit: 1000 });

        //some function definitions

        return modelBase;
    },
    'CurrentUser': {
        create: function (options) {
            options.data.MessageToPost = ko.observable("test");
            return ko.mapping.fromJS(options.data);
        }
    }
};

我参考了this post 来创建自定义映射,但它似乎不起作用,因为第二个 console.log 将相同的 JSON 输出到第一个。

另外,我尝试创建基于 this threadanother one 的嵌套映射选项,但也没有用。

var mappingOption = {
    create: function (options) {

        //modelBase, modifing UserName and add the functions

        var mappingOption2 = {
            'CurrentUser': {
                create: function (options) {
                    return (new(function () {
                        this.MessageToPost = ko.observable("test");
                        ko.mapping.fromJS(options.data, mappingOption2, this);
                    })());
                }
            }
        }
        return ko.mapping.fromJS(modelBase, mappingOption2);
    }
};

如何正确地将新属性添加到原始视图模型?

【问题讨论】:

    标签: javascript knockout.js


    【解决方案1】:

    来自 ko.toJS 的映射 documentation(toJS 和 toJSON 的工作方式与文档中所述的相同)

    • 取消映射

    如果要将映射对象转换回常规 JS 对象,请使用: var unmapped = ko.mapping.toJS(viewModel); 这将创建一个未映射的对象仅包含作为原始 JS 对象一部分的映射对象的属性

    如果您希望 json 包含您手动添加的属性,请使用 ko.toJSON 而不是 ko.mapping.toJSON 来包含所有内容,或者在首次创建对象时使用 include 选项来指定要添加的属性。

    var mapping = {
        'include': ["propertyToInclude", "alsoIncludeThis"]
    }
    var viewModel = ko.mapping.fromJS(data, mapping);
    

    编辑:在您的具体情况下,您的映射选项相互冲突。您已经为 CurrentUser 字段设置了特殊说明,但随后在 create 函数中覆盖了它们。我认为您的映射选项应该如下所示:

    var mappingOption = { 
      'CurrentUser': {
        create: function (options) {
          var currentUser = ko.mapping.fromJS(options.data, {
            'UserName': {
              create: function(options){
                return ko.observable(options.data);
              }
            },
            'include': ["MessageToPost"]
          });
          currentUser.MessageToPost = ko.observable("test");
          return ko.observable(currentUser).extend({ rateLimit: 1000 });
        }
      }
    };
    

    这是一个fiddle 的工作示例

    【讨论】:

    • 感谢您的回答,我设法通过从 toJS 中删除“映射”来输出整个视图模型。然而,确实我感兴趣的是向视图模型的子数组添加新属性的方法。我的代码成功地将属性添加到视图模型的根级别,但在嵌套级别时却没有这样做。
    • @seed.of.apricot 这是否解决了您的问题或者您仍然无法正常工作?
    • 感谢您的编辑,代码运行良好,我将对其进行修改以与我的项目集成。
    猜你喜欢
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多