1

1Ok so I'm developing an application that has a Parent-Child hierarchy using AngularJs to bind the data received from the RESTFUL web service to the view.

An example of the JSON the web service would be returning would be:

{"id":0,"name":"Parent One","listOfChildren":[{"id":0,"name":"Child 1","childType":"CHILD1"},{"id":1,"name":"Child 2","childType":"CHILD1"}]}

With this information I know I can put it into an array and display it on a table using Angulars ng-repeat but my problem is a Parent could have hundreds/thousands of children and there could be hundreds/thousands parents so the array would be colossal.

Another problem is when I update a parent with a new child I would have to traverse the whole array looking for the parent and then insert the child into it which is extremely ineffecient.

So my question is basically is there any way I can do this more efficiently without having to use one big array?

Thanks for any help provided.

Schokea
  • 708
  • 1
  • 9
  • 28
  • You should use a recursive `ng-include`. Have a look here: http://stackoverflow.com/questions/15661289/how-can-i-make-recursive-templates-in-angularjs-when-using-nested-objects – AlwaysALearner Nov 14 '13 at 13:02
  • in your example, the parent and both of the children have the same `id` property value of `0`. Is that actually the case? or do your parents and children have unique id's? – tennisgent Nov 14 '13 at 14:25
  • likely need to look closer at app and see where you can implement data on demand using routing or user interaction – charlietfl Nov 14 '13 at 15:37
  • Sorry they have the same id because It was a copy and paste error. – Schokea Nov 15 '13 at 12:00

1 Answers1

3

Given that you have a huge amount of data, I don't know that there is really a perfect solution. Do you have to show every parent and every child at one time? Or could you paginate the results so that you're only showing maybe 100 nodes at a time? in your example, the parent and both of the children have the same id property value of 0. Is that actually the case? or do your parents and children have unique id's? Do you have access to the backend web service? Can you change the format of the json it serves up?

Making some assumptions to the above questions, here's the best proposal I can think of:

Change your JSON into a format similar to this one:

var bigobject = {
    100: {
        "id":100,
        "name":"Parent One",
        "listOfChildren":{
            101: {
                "id":101,
                "name":"Child 1",
                "childType":"CHILD1"
            },
            102: {
                "id":102,
                "name":"Child 2",
                "childType":"CHILD1"
            }
            ...  // more children here
        }
    },
    103: {
        "id":103,
        "name":"Parent Two",
        "listOfChildren":{
            104: {
                "id":104,
                "name":"Child 3",
                "childType":"CHILD1"
            },
            105: {
                "id":105,
                "name":"Child 4",
                "childType":"CHILD1"
            }
            ...  // more children here
        }
    },
    ...  // more parents here
}

Basically you have one big json object where the key for every node is its node's id. And then you change a parent's listOfChildren from an array to an object that has the keys for all the id's of its children.

To add a new child to your parent, is simple. For example:

var parentId = 103;
var newChild = {"id":110,"name":"Child 2","childType":"CHILD1"};
bigobject[parentId].listOfChildren[newChild.id] = newChild;

And then to paginate your results, you could use the built-in limitTo filter and a custom filter startFrom:

.filter('startFrom', function() {
    return function(input, start) {
        if(!input) return input;
        start = +start;
        return input.slice(start);
    };
});

And then your ng-repeat would be something like:

<div ng-repeat="(parentId, parent) in bigobject | startFrom:start | limitTo:pageSize">
    <div ng-repeat="(childId, child) in bigobject[parentId].listOfChildren">
        {{parent.name}} - {{child.name}}
    </div>
</div>

I hope that helps or at least points you in a helpful direction.

tennisgent
  • 14,165
  • 9
  • 50
  • 48
  • Yes this is what I'm looking for... I have to paginate the results in the way you have specified... Thanks very much for the answer :) – Schokea Nov 15 '13 at 12:02
  • is it okay to store `bigobject` in the $scope? doesnt it reduce performance? And are there other places to store it except RAM? – pleerock May 15 '14 at 19:35