2015-09-30 2 views
5

Я разработал древовидное представление, которое использует нокаут для отображения иерархии. Я заметил странную ситуацию внутри хром, которая случается, когда я разрушаю узел в дереве. Текст для узла исчезает вместе с элементами под ним. Я понял, что у меня что-то не так с моим кодом, а потом выяснил, что он работает правильно и в IE, и в firefox. Я создал скрипку ниже, которая демонстрирует проблему с любым дополнительным кодом из моей страницы. Если вы разворачиваете узел и затем сворачиваете его (кнопка «плюс» не изменяется на минус, как в моем полном коде), текст исчезает. Затем вы можете просто щелкнуть в любом месте страницы, чтобы вернуть текст обратно.Хром ошибка с нокаутом?

Текст, который исчезает уже наметились в красном цвете, как это рекомендовано в комментариях и их можно увидеть на скриншоте

enter image description here

Я испытал это на 4 машины и на каждом из них она не работайте, когда я использую Chrome. Это ошибка в Chrome, или я делаю что-то неправильно? Кроме того, может ли кто-нибудь увидеть какой-либо способ обойти эту проблему, если это ошибка в 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>

+0

Ничего себе, это ужасно, но удивительно странное поведение ... – Jeroen

+0

Если я навешу 'span', который не отображается на вкладке« Элементы »панели инструментов Dev, поле * * выделено на странице, но текст действительно отсутствует. Странные вещи происходят. Было бы неплохо, если бы кто-нибудь мог проверить это в другом браузере веб-китов. – Jeroen

+0

Я предлагаю добавить '.hierarchyNode {border: 1px solid pink; } 'к вашему примеру, чтобы уточнить и, возможно, также [этот снимок экрана] (http://i.stack.imgur.com/qdjSx.png) или аналогичный, чтобы люди знали, что искать. – Jeroen

ответ

2

Я смог исправить это, изменив видимое связывание, чтобы вместо этого использовать параметр if. Я не знаю, почему это исправит, но ты туда.

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

fiddle

Это, как представляется, Chrome конкретной ошибка, потому что разметка явно не изменяются для элемента имени. Просто щелчок в любом месте после свертывания делает его видимым. Возможно, ошибка в рендерере?

1

Я надеюсь на конкурирующем ответ, или какой-либо помощи с моим собственным ответом, но в то же время: здесь обходной путь. Есть что-то с свойством display того span. Я немного сократил ваш пример, все еще мог воспроизвести проблему и смог «исправить» ее, установив явное правило display. Смотрите это:

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. Чтобы ответить на еще одну часть вашего вопроса, я предполагаю, что это действительно ошибка в Chrome.

+0

Вы правы, что устраняет проблему в моем упрощенном примере. К сожалению, я просто попробовал это в своем полном коде, и это не устраняет проблему. Мне нужно будет изучить модификацию этой работы, чтобы увидеть, могу ли я заставить ее работать на моей полной веб-странице. По крайней мере, это дает мне идею начать с моего кода. – WizKid