给定一个Knockout observableArray,可以添加和删除哪些项目,如何使用Isotope布置相应的HTML元素?例如考虑下面的HTML,它声明了一个div #container
,它应该用Knockout填充子div:
<div id="container" data-bind="foreach: items, click: addItem">
<div class="item show" data-bind="text: text, click: $parent.removeItem, clickBubble: false"></div>
随附的JavaScript使用几个项目预先填充容器,并允许用户单击项目以删除它们并单击容器以添加新项目(通过Knockout):
function ItemModel(parent) {
var value, self = this,
found;
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);
return false;
};
this.addItem = function () {
self.items.push(new ItemModel(self));
};
};
ko.applyBindings(new ViewModel("Test"));
当与Isotope正确配合时,物品应由Isotope自动布局,包括物品被移除,添加和移动时。
请参阅this fiddle了解该概念的演示。
答案 0 :(得分:0)
我已经能够通过编写一个名为Knockout-Isotope的特殊Knockout绑定将Knockout与Isotope集成。这有助于大大整合这两种技术,并确保Isotope与Knockout视图模型保持同步。请参阅下面的代码,了解如何将此绑定与Knockout observableArray一起使用,或尝试实时fiddle。
请注意,此绑定依赖于Knockout的分支以便工作。
<强> 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"));
答案 1 :(得分:0)
这可能是一种解决方案......或者是一种开始的方式
<div id="Items" data-bind=" foreach: Items">
<div class="item" data-bind="masonry: { container: '#Items' }">
</div>
</div>
ko.bindingHandlers.masonry = { init:function(element,valueAccessor,allBindingsAccessor,viewModel,bindingContext){
}, update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { var $el = $(element); var value = ko.utils.unwrapObservable(valueAccessor()); var container = document.querySelector(value.container); var msnry = Masonry.data(container); if (!msnry) { var msnry = new Masonry(container); } msnry.addItems($el) msnry.layout(); msnry.bindResize(); },
};