Chrome knockout error?

I developed a tree view that uses knockout to display a hierarchy. I noticed a strange situation inside chrome that occurs when I destroy a node in a tree. The text for the node disappears along with the elements below it. I realized that I had something wrong with my code, and then found out that it works correctly in both IE and firefox. I created the fiddle below which demonstrates the problem with any additional code from my page. If you expand the node and then collapse it (the plus button does not change to minus, as in my full code), the text will disappear. Then you can simply click anywhere on the page to bring the text back.

Text that disappears has been highlighted in red, as recommended in the comment, and can be seen in the screenshot.

enter image description here

I tested this on 4 machines, and on each of them it does not work when I use Chrome. Is this a bug in Chrome, or am I doing something wrong? Also, can anyone see any way around this issue if this is a bug in Chrome?

Script example

console.clear(); var hierarchyNode = function (parent) { var self = this; this.name = "Node Name"; this.hasChildren = ko.observable(true); this.childNodes = ko.observableArray(); this.expanded = ko.observable(false); }; hierarchyNode.prototype = { name: null, hasChildren: null, childNodes: null, getChildNodes: function (element, event) { if (element.hasChildren() === true && element.childNodes().length === 0) { element.childNodes.push(new hierarchyNode(element)); } element.expanded(!element.expanded()); } }; var hierarchyVM = function () { var self = this; self.hierarchyNodes = ko.observableArray(); self.selectItem = function () {}; }; var vm = new hierarchyVM(); vm.hierarchyNodes.push(new hierarchyNode(null)); console.log(vm.hierarchyNodes()[0]); ko.applyBindings(vm); 
 ul.tree { list-style-type: none; padding-left: 10px; } .hierarchyNode {border: 1px solid red;} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul class="tree" data-bind="template: { name: 'itemTmpl', foreach: $data.hierarchyNodes }"></ul> <script id="itemTmpl" type="text/html"> <li> <button data-bind="click: getChildNodes">+</button> <div data-bind="visible: hasChildren() == false" class="tree-spacer"></div> <span data-bind="text: name" class="no_selection hierarchyNode"></span> <ul class="tree" data-bind="template: { name: 'itemTmpl', foreach: $data.childNodes }, visible: expanded"></ul> </li> </script> 
+5
source share
2 answers

I managed to fix this by changing the visible binding to use the if parameter in the template instead. I don’t know why this will fix, but there you go.

 <ul data-bind="template: { name: 'itemTmpl', foreach: childNodes, 'if': expanded }"></ul> 

fiddle

This seems like a specific Chrome bug, since the markup does not explicitly change for the name element. Just clicking anywhere after folding makes it visible. Perhaps a bug in the renderer?

+2
source

I hope for a competing answer or some help with my own answer, but in the meantime: here is a workaround. There is something disabled with the display property of this span . I slightly reduced your example, I could still reproduce the problem and was able to “fix” it by setting an explicit display rule. See this:

 var hierarchyNode = function (parent) { var self = this; self.name = "Some node"; self.childNodes = ko.observableArray([]); self.expanded = ko.observable(false); self.getChildNodes = function (element, event) { if (self.childNodes().length === 0) { self.childNodes.push(new hierarchyNode(self)); } self.expanded(!self.expanded()); } }; var hierarchyVM = function () { var self = this; self.hierarchyNodes = ko.observableArray([new hierarchyNode(null)]); }; ko.applyBindings(new hierarchyVM()); 
 .node-name { border: 1px solid red; } /* Workaround: */ .node-name { display: inline-block; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <ul class="tree" data-bind="template: { name: 'itemTmpl', foreach: $data.hierarchyNodes }"></ul> <script id="itemTmpl" type="text/html"> <li> <button data-bind="click: getChildNodes">+</button> <span data-bind="text: name" class="node-name"></span> <ul data-bind="template: { name: 'itemTmpl', foreach: childNodes }, visible: expanded"></ul> </li> </script> 

PS. To answer another part of your question, I assume this is really a bug in Chrome.

+1
source

Source: https://habr.com/ru/post/1232639/


All Articles