KnockoutJS - Nested Data, Loading Children

2019-05-12 04:23发布

问题:

I am very very new to knockoutjs - having worked through the tutorials and I have made a nice start. I have application which seems well suited to KO. In that I need to populate a table with data from JSON. This data is nested, and can be nested at any depth, but my API will only ever return data two levels deep.

E.g.

  • Node 1
    • Node A
    • Node B

I've managed to get the data to load into my table, lovely. I've taken this a step further and have supported nesting. I have a requirement so that if a Node has children, it can be injected beneath the Node into the table.

An example of this would be...

  • Node 1 (HasChildren)
    • Node A
    • Node B (HasChildren)

As Node B 'HasChildren', I would like to allow the loading of it's children into the table, beneath Node B. In this event, I would be able to query my API, and it would return the children for Node B

  • Node 1
    • Node A
    • Node B
      • Node B1
      • Node B2

I've got something roughly working, but it only works on a level 1 node. Once it get's to level2, can't seem to find my method (addChild). I can't work out why it cannot find the method, as it is in my ViewModel.

The post below, goes a long way to fixing this part of the problem.

Help!

I've pasted the code here... (if you scroll to the right on the table, you can click open, to see, what's happening!)

http://jsfiddle.net/8k6pj/1/ - Original Version (18th April 2012)

http://jsfiddle.net/8k6pj/6/ - Latest Version

Many thanks in advance!

Laurence

p.s Have further updated my code, so although I'm a bit stuck on the above, have started looking into implementing how the code will postback so we can save.

It looks like the postback is working, however it does not post back the changed values, the original values are posted back. Think this is because I need to use an ObservableArray, exploring that now.

回答1:

I've had a go at understanding what you would like to happen, I'm still a bit unclear but thought I'd submit what I did in order to provoke more info if needed.

Your question title mentions nesting but from your code it appears you aren't nesting anything, instead you are flattening your nested parent child objects.

Instead of using jquery delegates which I would not recommend since it breaks encapsulation of your models, I changed your template to use click bindings and placed an open function on the Crew/Component objects.

<td rowspan="3">
    <a data-bind="click: open">Open</a>
    <a>Save</a>
</td>

I also noticed that your addChild method requires you to pass an array to it. Your original code would not have worked as the Crew objects don't themselves have a Crews collection so i took a guess an used the Crews collection on their parent Component.

All these alterations meant I had to pass through the root viewModels and the parent components on the constructors.

http://jsfiddle.net/madcapnmckay/fdb5r/2/

FYI - This fiddle still throws errors when clicking Open as the Allocated objects don't get initialized correctly. I've left this upto you to fix since I don't understand the domain enough to fix it myself. The adding behavior works correctly though.

EDIT after updated question

Here's a re factored and simplified example that should get you started. I removed a lot of the non-essential stuff to make it clearer how it works.

http://jsfiddle.net/madcapnmckay/xxGam/

Hope this helps.



回答2:

I would suggest taking a look at ko.mapping to handle some of the data loading you are working on. I think it will help out with some of the data issues you are having

http://knockoutjs.com/documentation/plugins-mapping.html



标签: knockout.js