knockoutjs mapping:在树中添加observable

时间:2015-04-16 13:37:48

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

我使用knockoutjs来形象化树。我有一个初始的AJAX调用来加载孔树。使用knockout-mapping-plugin进行映射。一切都很好:)感谢这个伟大的软件。

我的问题是:我想在模型中添加额外的observable。我可以使用映射选项来做到这一点。

对象:

{ id: ko.observable(), parentID: ko.observable(), description: ko.observable(), children: ko.observableArray() }

Mappingoptions:

var mappingOptions = {
            create: function (options) {
                console.log("create");
                var vm = ko.mapping.fromJS(options.data);
                vm.newObservable = ko.observable(true);
                return vm;
            }
        };

映射:

ko.mapping.fromJS(response, mappingOptions, self.nodes);

响应是对象(节点)列表。 self.nodes是observableArray(),它包含对象(节点)列表

每个节点都有children-observalbeArray,它们也包含节点(带子节点) 所以没什么特别的,这基本上就是树的运作方式:)

但是这只会将这个新的observable添加到根节点。我希望每个孩子和孩子的孩子都有这种额外的可观察性(等等......)。

我试过了:

var mappingOptions = {
    create: function (options) {
        console.log("create");
        var vm = ko.mapping.fromJS(options.data);
        vm.newObservable = ko.observable(true);
        return vm;
    },
    'children': {
        create: function (options) {
            console.log("children.create");
            options.data.newObservable = ko.observable(true);
            return ko.mapping.fromJS(options.data);                    
        }
    }
};

我在互联网上找到了这个地方。它不起作用。

有人可以帮助我吗?

谢谢!

P.S。:我无法提供一个小提琴,因为服务似乎已经被破解(或者我的防火墙正在阻止它:()

1 个答案:

答案 0 :(得分:0)

我会尝试创建数据模型。我们称之为Node

var Node = function Node(data) {
  this.parentID    = ko.observable( data.parentID );
  this.description = ko.observable( data.description );
  this.children    = ko.observableArray([]);

  data.children.forEach(function(child) {
    this.children.push( new Node(child) );
  }, this);
}

这样可以轻松地在您希望的每个节点上创建任何其他属性。

在你的viewmodel中:

var Viewmodel = function Viewmodel() {
  this.nodes = ko.observableArray([]);

  this.getResponse = function getResponse() {
    // response is loaded here

    response.forEach(function(node) {
      this.nodes.push( new Node(node) );
    }, this);
  };
}

请注意我在这里使用原生Array.prototype.forEach。如果你需要支持IE< 9,你可以用Knockouts替换它ko.utils.arrayForEach