Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chrome Bug with Knockout?

I have developed a tree view that uses knockout to display a hierarchy. I have noticed a weird situation within chrome that happens when I collapse a node in the tree. The text for the node disappears along with the items under it. I figured I had something wrong with my code and then figured out that it works correctly in both IE and firefox. I created the fiddle below that demonstrates the issue with any extra code from my page stripped out. If you expand a node and then collapse it (the plus button does not change to a minus as it would in my full code), the text disappears. Then, you can just click anywhere on the page to get the text to show back up.

The text that disappears has been outlined in red as recommended in a comment and can be seen in the screenshot

enter image description here

I have tested this out on 4 machines and on each one it doesn't work when I use Chrome. Is this a bug in Chrome, or am I doing something wrong? Also, can anybody see any way to work around this issue if it is a bug in Chrome?

Example Fiddle

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>
like image 390
WizKid Avatar asked Oct 19 '22 01:10

WizKid


1 Answers

I was able to fix it by changing the visible binding to use an if parameter on the template instead. I don't know why this would fix it, but there you go.

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

fiddle

This does seem to be a Chrome specific bug because the markup is clearly not being changed for the name element. Just clicking anywhere after collapsing makes it appear. A bug in the renderer perhaps?

like image 196
Jeff Mercado Avatar answered Oct 30 '22 04:10

Jeff Mercado