javascript - Why are these Knockout subscriptions notifying an object that shouldn't have subscriptions at all -


check out here:jsfiddle

here's html:

<script src="http://code.jquery.com/jquery-2.1.4.min.js" ></script>  <div id="first"> <button data-bind="click: togglecolumn">click me!</button> </div> <ul id="list_test">     <!-- ko foreach: list -->     <li data-bind="text: $data.colname"></li>     <!-- /ko --> </ul> 

here's javascript:

function viewmodel(){     var self = this;     self.showcolumn = ko.observable(true);     self.togglecolumn = function(){         self.showcolumn(!self.showcolumn());     };      self.listofobjects = [         {colname: 'test1', visible: self.showcolumn},         {colname: 'test2'},         {colname: 'test3', visible: self.showcolumn},         {colname: 'test4'},         {colname: 'test5'},     ];  };  function testviewmodel(params){     var self = this;     self.list = ko.observablearray();     for(var = 0; < params.length; i++){         var obj = params[i];         if(!obj.visible){             //obj.visible = ko.observable(true);         }          if(obj.visible){             obj.visible.subscribe(function(){                     var elements = $('li');                     for(var = 0; < elements.length; i++){                         if($(elements[i]).text() == obj.colname){                             $(elements[i]).hide();                         }                     }                 });         }          self.list.push(obj);    } }  function initviewmodel(){      var mod = new viewmodel();     ko.applybindings(new testviewmodel(mod.listofobjects),document.getelementbyid("list_test"));     ko.applybindings(mod,  document.getelementbyid("first"));   }  initviewmodel(); 

so issue this. why when click button, 'test5' list item gets hidden , not 2 subscribed objects (test1 , test3)? seems default hiding end of list.

i've done actual code, since jsfiddle barebone replication of error, , examined through chrome's console / debugger.

within subscribe call, obj.visible property when compared showcolumn variable not same instance. if getsubscriptionscount on obj.visible inside subscribe call 1 subscription should never have gotten in first place because never should have been defined. if on 'test1' , 'test3' visible properties 2 subscriptions (as expected) , references same instance viewmodel.showcolumn.

still within subscribe call, if check value of obj, you'll get

{colname: 'test5', visible: /*some knockout obj*/} 

it never should have called subscribe 'test5'. should have called 'test1' , 'test3'.

now, how obj.visible.subscribe notified 'item5' when 'item5' object never received reference viewmodel.showcolumns? how possible visible defined 'item5'?

to me, looks subscribe on different ko.observable object notifying subscribe on different (non-existent even) ko.observable. i'm pretty sure shouldn't happening...

that's classic "closure" bug. obj variable changing during life of for loop, , last value holds points "test5". event handler function uses same variable, when event fired, looks "test5" , hides that. can solve standard closure & iife.

here's important code:

if(obj.visible){   (function (obj) {     obj.visible.subscribe(function(){       var elements = $('li');       for(var = 0; < elements.length; i++){         if($(elements[i]).text() == obj.colname){           $(elements[i]).hide();         }       }     });   })(obj); } 

here's fixed fiddle.


Comments

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -