javascript - Update an angular treeview directive when a new object is added to the collection -


i have treeview directive credit http://codepen.io/bachly/pen/kwwrzg being starting block. trying update when add objects collection. can update object , insert new objects treeview directive never called once $scoped item updated. data used come service @ point testing mock data.

the original collection looks this

$scope.mylist = {             children: [               {                   name: "event",                   children: [                     {                         name: "event date",                         parent:"event",                         children: [                           {                               name: "2008",                               filtertype: '_eventstartdate',                               parent: 'event'                           },                           {                               name: "2009",                               filtertype: '_eventstartdate',                               parent: 'event'                           }                         ]                     },                     {                         name: "event attendee",                         parent: "event",                         children: [                           {                               name: "person 1",                               filtertype: '_eventattenddeename',                               parent: 'event attendee'                           },                           {                               name: "person 2",                               filtertype: '_eventattenddeename',                               parent: 'event attendee'                           }                         ]                     }                   ]               }]    };      var theothercollection = {        children: [          {              name: "a new event",              children: [                {                    name: "the other date",                    parent: " new event",                    children: [                      {                          name: "2010",                          filtertype: '_eventstartdate',                          parent: '_event'                      },                      {                          name: "2011",                          filtertype: '_eventstartdate',                          parent: '_event'                      }                    ]                }              ]          }]    }; 

this generates tree view checkboxes using following directive , html

app.directive('tree', function () {     return {         restrict: 'e',          replace: true,         scope: {             t: '=src',             filter: '&'         },         controller: 'treecontroller',         template: '<ul><branch ng-repeat="c in t.children track $index"  src="c" filter="dosomething(object, isselected)"></branch></ul>'     }; });  app.directive('branch', function($compile) {      return {         restrict: 'e',          replace: true,          scope: {             b: '=src',             filter: '&',             checked: '=ngmodel'         },              template: '<li><input type="checkbox" ng-click="innercall()" ng-model="b.$$hashkey" ng-change="statechanged(b.$$hashkey)" ng-hide="visible" /><a>{{ b.name }}</a></li>',             link: function (scope, element, attrs) {                 var clicked = '';                var haschildren = angular.isarray(scope.b.children);                 scope.visible = haschildren;                 if (haschildren) {                     element.append('<tree src="b"></tree>');                     $compile(element.contents())(scope);                 }                 element.on('click', function(event) {                     event.stoppropagation();                     if (haschildren) {                         element.toggleclass('collapsed');                     }                 });                 scope.statechanged = function(b) {                     clicked = b;                 };                  scope.innercall = function() {                     scope.filter({ object: scope.b, isselected: clicked });                 };             }         };     }); 

and html

  <div ng-controller="treecontroller">         <tree src="mylist" iobj="object" filter="dosomething(object, isselected)"></tree>          <a ng-click="clicked()"> link</a>     </div> 

when checkbox clicked new collection added existing 1 using lodashjs

ng-click event

$scope.dosomething = function (object, isselected) {     if (isselected) {         var item = object;         console.log(item);         nestassociation(object, $scope.mylist, theothercollection);     } } 

which creates new array , adds within children array

function nestassociation(node, oldcollection, newaggregates) {     // var item = fn(oldcollection, node.parent);     var updatedarray = _.concat(oldcollection.children, newaggregates);     console.log(updatedarray);     if (updatedarray != null)         updatemylist(updatedarray); } 

i can see in output have new object can't treeview update. have tried within directive add $compile(element) on click event in directive since array not built yet nothing changes.

do need add $watch directive , if or there other way can directive re-render , display new nested collection?

update

base on of feedback , questions here little more detail around question. issue seeing not in directive far moving data around issue cannot treeview re-render once array added existing model. following link is working plunker shows project works. running chrome dev tools can see in output model updated after checkbox selected enter image description here

while see object updated, directive never updates show new array added object. part need understanding.

thanks in advance

you pass function inner directives (which best practice), have access scope.filter. not dosomethingfunction. 1 undefined there.

filter="dosomething(object, isselected)"
=>
filter="filter(object, isselected)"

app.directive('tree', function () {     return {         restrict: 'e',          replace: true,         scope: {             t: '=src',             filter: '&'         },         controller: 'treecontroller',         template: '<ul>                       <branch ng-repeat="c in t.children track $index"                           src="c" filter="filter(object, isselected)">                       </branch>                     </ul>'     }; }); 

next :

you can never access $$ variables in angularjs, because private. maybe should make 1 db..., $$hashkey seems easy solution though.

checked attribute might throw error, because ngmodel not exist on tree directive template. (put @ least ? before)

a checkbox can not have model $$hashkey.
ng-change , ng-click called @ same time, use simplest one.

app.directive('branch', function($compile) {      return {         restrict: 'e',          replace: true,          scope: {             b: '=src',             filter: '&'         },              template: '<li><input type="checkbox" ng-click="innercall(b.$$hashkey)" ng-model="ischecked" ng-hide="visible" /><a>{{ b.name }}</a></li>',             link: function (scope, element, attrs) {                 scope.ischecked = false;                var haschildren = angular.isarray(scope.b.children);                 scope.visible = haschildren;                 if (haschildren) {                     element.append('<tree src="b"></tree>');                     $compile(element.contents())(scope);                 }                 element.on('click', function(event) {                     event.stoppropagation();                     if (haschildren) {                         element.toggleclass('collapsed');                     }                 });                  scope.innercall = function(hash) {                     if(scope.ischecked){                        scope.filter({ object: scope.b, isselected: hash });                     }                  };             }         };     }); 

update

you have same treecontroller in tree directive , in index.html view. this causes view not update!

i deleted 1 in directive, otherwise you'll have controller each child.
saw console.log message in controller, in controller 1 directive.
not accessing controller of index.html.

then fixed filter function communication between childs :

you forgot communicate filter function when append new tree's :

element.append('<tree src="b" filter="filter({ object: object, isselected: isselected })"></tree>');

also, in parent directive template, need hash send parameters function :
filter="filter({ object: object, isselected: isselected })"

i edited plunker here without changing code above comments made.
(i'm not sure write not want , because did not comment rather not change still undertand code fast)
view updating now!
think little debug want , comments above should enough.

edit 2
forgot return object property chrilden. returned array, caused problem.

function updatemylist(data) {       var transformed = { children : data };         $scope.mylist = transformed;     } 

here working plunker.


Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -