4

我一直试图让 Isotopejs 和 Knockoutjs 一起工作。所以,除了当我需要向 dom 添加元素然后需要删除它们时,它一直在流畅地工作。

我已经将问题追溯到这个方法内部:ko.utils.setDomNodeChildrenFromArrayMapping = function (domNode, array, mapping, options, callbackAfterAddingNodes) { .. }

哪个调用此方法 fixUpVirtualElements(lastMappingResult[lastMappingResultIndex].domNodes);

fixUpVirtualElements 方法正在删除我需要在 beforeRemove 事件中使用同位素删除的 dom 节点;foreach 绑定调用没有获取需要删除的元素。

我已经阅读了淘汰赛中该方法的注释。但我不明白它们的含义,因为我没有任何领域知识来了解它所谈论的内容。

任何人都可以看看我最新的 jsfiddle,让我知道为什么 fixUpVirutalElements 正在删除我需要传递给 beforeRemove 事件的元素。

http://jsfiddle.net/evanlarsen/C5y6G/

有人可以修复这个 jsFiddle 以使 2 个库一起工作。

谢谢,埃文拉森

4

2 回答 2

5

我不是同位素专家;我知道它的作用,但我不知道它的算法,但是我对 knockout.js 的来源有深入的了解。现在可能的问题是同位素操纵了由敲除模板绑定创建的dom节点。knockout.js 不允许其他程序接触由模板创建的 DOM 节点。所有的 knockout.js 算法都假定更改模板创建的 dom 节点的唯一方法是操作绑定到模板的数组。如果其他东西直接操纵该节点,无论是通过添加节点、删除节点还是(如在同位素的情况下)重新排序它们......所有淘汰赛 js 算法都会发疯......这意味着删除的节点不会消失,一些节点是重复的...等等。

- - - - - - - - - - - - 更新 - - - - - - - -

解决了只是替代:

self.serviceAdded = function(el) {
        if (el && el.nodeType === 1) {
           $('#container').isotope('insert', $(el)); 

        }
    };

和:

self.serviceAdded = function(el) {
        if (el && el.nodeType === 1) {
           $('#container').isotope('appended', $(el)); 

        }
    };
于 2012-07-17T08:00:00.490 回答
1

我认为结合 Isotope 和 Knockout 的最佳选择是通过对后者的绑定。为此,我编写了一个名为Knockout-Isotope 的文章。请注意,它需要Knockout的分叉版本,但希望我所做的微小更改可以在某个时候集成回来。

由于我刚刚完成了 Knockout-Isotope,它没有经过很好的测试,但它至少可以处理我到目前为止所遇到的场景。

代码

演示小提琴

HTML:

<h1>Knockout Isotope Binding Demo</h1>
<p>This is a demonstration of the 
 <a href="https://github.com/aknuds1/knockout-isotope">Knockout-Isotope</a>
 binding for <a href="http://knockoutjs.com/">Knockout</a>, which visualizes
 Knockout observableArrays through
 <a href="http://isotope.metafizzy.co/index.html">Isotope</a>.
</p>

<p>Click on an item to remove it or click in the item container to add a new item</p>
<div id="container" data-bind="isotope: { data: items, isotopeOptions: getOptions }, click: addItem">
  <div data-bind="text: text, click: $parent.removeItem, clickBubble: false"></div>
</div>

JavaScript:

function ItemModel(parent) {
    var value, self = this,
        found, i;
    for (value = 0; value < parent.items().length; ++value) {
        found = false;
        for (i in parent.items()) {
            var item = parent.items()[i];
            if (item.value() == value) {
                found = true;
                break;
            }
        }
        if (!found) {
            break;
        }
    }
    this.value = ko.observable(value);

    this.text = ko.computed(function () {
        return "Item " + self.value();
    });
}

var ViewModel = function () {
    var self = this;
    self.items = ko.observableArray();
    self.items.push(new ItemModel(self));
    self.items.push(new ItemModel(self));

    this.removeItem = function (item) {
        self.items.remove(item);
    };

    this.addItem = function () {
        self.items.push(new ItemModel(self));
    };

    // Knockout callback for getting Isotope options
    this.getOptions = function () {
        return {
            masonry: {
                columnWidth: 210
            }
        };
    };
};

ko.applyBindings(new ViewModel("Test"));
于 2013-02-17T13:50:32.273 回答