Skip to content Skip to sidebar Skip to footer

Angularjs : How To Create Dom And Bind To A Model Based On Arbitrary Hierarchical Data

Angularjs: complex directive in ng-repeat, how to bind the ngModel or ngChecked in directive and make it work? given the array: +----+-----------+----------+----------+-------+ | i

Solution 1:

Basically, what you are looking for is to create an arbitrary hierarchical DOM structure and bind it to some equal hierarchical data structure (or ViewModel).

How you represent your hierarchy - I'll leave it up to you. It's not essential for the question.

For simplicity, suppose we model the hierarchy as a tree structure:

$scope.tree= {n:"root", v:false, 
      c: [
        {n:"L11", v:false, c: []},
        {n:"L12", v:false, c: [
          {n:"L21", v:true, c: [
            {n:"L31", v:false, c:[]}
            ]}
          ]}
        ]};

You then need to traverse this tree and create DOM elements bound to some object o (bear with me):

<div><inputng-model="o.v">{{o.n}}</div>

Then, this needs to be compiled against a scope. But since the structure is arbitrary, you could create a new child scope for each node.

So, what is o? o will be the object we will create on each child scope created for each node of the tree.

So, suppose you have a recursive function traverseTree, that 1) creates the DOM element, 2) compiles against this scope, and 3) creates a child scope for each child. It could look like something as follows:

functiontraverseTree(n, scope, parent){
  var me = angular.element("<div><input type='checkbox' ng-model='o.v'>{{o.n}}</div>");
  $compile(me)(scope);
  parent.append(me);

  for (var i = 0; i < n.c.length; i++) {
    var c = n.c[i];
    var childScope = scope.$new(true);
    childScope.o = c; // set object "o" on the scope

    traverseTree(c, childScope, me);
  }
}

The directive's link function kicks off the tree traversal:

app.directive("tree", function($compile){

  functiontraverseTree(n, scope, parent){
     // as above
  }

  return {
    restrict: "A",
    scope: {
      root: "=tree"
    },
    link: function(scope, element, attrs){
      var childScope = scope.$new(true);
      childScope.o = scope.root;

      traverseTree(scope.root, childScope, element);
    }
  };

});

The usage is:

<divtree="tree"></div>

Here's a plunker

Solution 2:

I am sorry I just saw so here is my 2 pence for everyone's benefit.

Assuming

$scope.tree= {n:"root", v:false, 
  c: [
    {n:"L11", v:false, c: []},
    {n:"L12", v:false, c: [
      {n:"L21", v:true, c: [
        {n:"L31", v:false, c:[]}
        ]}
      ]}
    ]};

We can do

<scripttype="text/ng-template"id="Tree"><inputtype='checkbox'ng-model='o.v'>{{o.n}}
    <png-if="o.c"><png-repeat="o in o.c"ng-include="'Tree'"></p></p></script><div><png-repeat="o in tree"ng-include="'Tree'"></p></div>

Sorry have not tested this snippet did not have time, but this is the way it can work without coding on a hierarchal structure. Have used it many times.

Post a Comment for "Angularjs : How To Create Dom And Bind To A Model Based On Arbitrary Hierarchical Data"