knockout.js在一个视图模型中单击并基于该视图呈现其他视图模型

时间:2017-04-11 13:59:10

标签: javascript asp.net-mvc knockout.js

    <div data-bind="with: SimpleListModel">  
<div data-bind="foreach: parents">   
        <span data-bind="text: parentname"></span> 
    </div>
</div>

<div data-bind="with: SimpleListModel2">  
    <div data-bind="foreach: childrens">   
        <span data-bind="text: childname"></span>
    </div>
</div>

这是我的viewmodel

var parentsdata= [
{ parentid:1, parentname: "Danny" },{parentid:2, parentname: "Peter" },{parentid:3, parentname: "shawn" }];

var childdata= [
{ parentid:1, childrens: [
    { childname: "child1"},
    { childname: "child2"}]
},
{ parentid:2, childrens: [
    { childname: "child1"},
    { childname: "child2"}]
}];

var SimpleListModel = function(parents) {
  var self= this;
 self.parents= ko.observableArray(parents);
};

var SimpleListModel2 = function(childrens) {
 var self= this;
 self.childrens= ko.observableArray(childrens);
};

var masterVM = (function () {
         var self = this;         
         self.SimpleListModel= new SimpleListModel(parentsdata);
          self.SimpleListModel1= new SimpleListModel1(parentsdata);

})();

ko.applyBindings(masterVM);

我想让父名可点击,以便当我点击我的父名时,它的子项将填充在2视图模型中。我怎么能这样做?

2 个答案:

答案 0 :(得分:1)

首先,你没有SampleListViewModel1。您需要将其更改为SampleListViewModel2,然后在初始化期间将childdata传递给该对象,而不是parentdata

然后,您可以在SampleListViewModel1中创建一个函数,该函数将所选父项传递给父对象(masterVM)。然后在masterVM中,尝试从所选父项中获取子项并将其存储在可观察对象中。在视图中,您只需要显示此可观察对象。

var parentsdata = [
  { parentid:1, parentname: "Danny" },
  {parentid:2, parentname: "Peter" },
  {parentid:3, parentname: "shawn" }
];

var childdata = [
  { parentid:1, childrens: [
    { childname: "child1 of parent1"},
    { childname: "child2 of parent1"}]
  },
  { parentid:2, childrens: [
    { childname: "child1 of parent2"},
    { childname: "child2 of parent2"}]
  }
];

var SimpleListModel = function(parents, parentObject) {
  var self = this;

  // this is used to get the reference to parent object (masterVM)
  self.parentObject = parentObject;

  self.parents = ko.observableArray(parents);

  // call this function on click and trigger the parent function which will do the filtration
  self.selectParent = function(parent) {
    self.parentObject.selectParent(parent);
   }
};

var SimpleListModel2 = function(childrens) {
  var self = this;
  self.childrens = ko.observableArray(childrens);
};

function masterVM() {
  var self = this;         
 
  // pass its own object during initialization
  self.SimpleListModel = new SimpleListModel(parentsdata, self);

  self.SimpleListModel2 = new SimpleListModel2(childdata);

  // store children of the selected parent
  self.childForSelectedParent = ko.observable(null);

  // get the children of the selected parent
  self.selectParent = function(parent) {
    var children = ko.utils.arrayFirst(self.SimpleListModel2.childrens(), function(children) {
        return children.parentid === parent.parentid;
    });
    if(children)
      self.childForSelectedParent(new SimpleListModel2(children.childrens));
    else
      self.childForSelectedParent(null);
  };
}

ko.applyBindings(new masterVM());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div>Click on any of the name</div>

<div data-bind="with: SimpleListModel">  
  <div data-bind="foreach: parents">   
    <span data-bind="text: parentname, click: $parent.selectParent"></span> 
  </div>
</div>

<div data-bind="with: childForSelectedParent">  
  <div data-bind="foreach: childrens">   
    <span data-bind="text: childname"></span>
  </div>
</div>

答案 1 :(得分:1)

我喜欢上面children发布的答案,但很少有更正。

而不是每次点击父时使用功能来过滤var parentsdata = [{ parentid: 1, parentname: "Danny" }, { parentid: 2, parentname: "Peter" }, { parentid: 3, parentname: "shawn" }]; var childdata = [{ parentid: 1, childrens: [{ childname: "DannyChild1" }, { childname: "DannyChild2" } ] }, { parentid: 2, childrens: [{ childname: "PeterChild1" }, { childname: "PeterChild2" } ] } ]; var SimpleListModel = function(parents) { var self = this; self.parents = ko.observableArray(parents); }; var SimpleListModel2 = function(childrens) { var self = this; self.childrens = ko.observableArray(childrens); }; var masterVM = (function() { var self = this; self.SimpleListModel = new SimpleListModel(parentsdata); self.SimpleListModel2 = new SimpleListModel2(childdata); self.selectedParent = ko.observable(); // holds selected parent self.ParentChildrens = ko.computed(function() { return ko.utils.arrayFilter(self.SimpleListModel2.childrens(), function(child) { return child.parentid == self.selectedParent(); })[0]; }); self.parentClick = function(data) { self.selectedParent(data.parentid); } })(); ko.applyBindings(masterVM); ,您可以使用ko.computed自动完成工作。这样你就可以动态地改变父亲,你的两个父子模型保持不变。

&#13;
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="with: SimpleListModel">
  <div data-bind="foreach: parents">
    <span data-bind="text: parentname, click: parentClick"></span>
  </div>
</div>

<div data-bind="with: ParentChildrens">
  <div data-bind="foreach: childrens">
    <span data-bind="text: childname"></span>
  </div>
</div>
&#13;
animal_id   trait_id    sire_id dam_id
    1         25.05        0       0
    2         -46.3        1       2
    3          41.6        1       2
    4         -42.76       3       4
    5         -10.99       3       4
    6         -49.81       5       4
&#13;
&#13;
&#13;