Как разместить HTML-элементы для элементов в Knockout observableArray с помощью Isotope?

Учитывая наблюдаемый массив Knockout, в который можно добавлять и удалять элементы, как мне разместить соответствующие элементы HTML с помощью Isotope? Рассмотрим, например, следующий HTML-код, в котором объявляется div #container, который должен быть заполнен дочерними div с помощью Knockout:

<div id="container" data-bind="foreach: items, click: addItem">
<div class="item show" data-bind="text: text, click: $parent.removeItem, clickBubble: false"></div>

The accompanying JavaScript pre-populates the container with a couple of items, and lets the user click on items to delete them and click in the container to add new items (via 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, в том числе при удалении, добавлении и перемещении элементов.

См. эту скрипту для демонстрации концепции.


person aknuds1    schedule 12.02.2013    source источник


Ответы (2)


Мне удалось интегрировать Knockout с Isotope, написав специальную привязку Knockout под названием Knockout-Isotope. Это значительно облегчает интеграцию двух технологий и обеспечивает синхронизацию Isotope с моделью представления Knockout. В приведенном ниже коде показан пример использования этой привязки с Knockout observableArray, или попробуйте живая скрипка.

Имейте в виду, что эта привязка зависит от ответвления 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"));
person aknuds1    schedule 12.02.2013

это может быть решением... или способом начать

 <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();
},

};

person Gerardo Gandia    schedule 31.10.2013