I am using knockoutjs with masonry and have created a custom knockout binding handler to apply masonry to a html element.
The container I want to apply masonry to has it's content injected dynamically using knockout's foreach
binding.
The issue I am having is getting masonry to apply itself after the masonry container has been updated dynamically.
In the snippet example if you click the masonryize button then it will destroy the masonry container and reapply mansonry, how do I get this behaviour into my binding handler?
ko.bindingHandlers.masonry = {
update: function(element, valueAccessor) {
var options = valueAccessor();
$(element).masonry(options);
}
}
var vm = {
term: ko.observable(),
page: ko.observable(1),
per_page: ko.observable(3),
items: ko.observableArray(),
masonryize: function() {
$('.grid').masonry('destroy');
$('.grid').masonry({
itemSelector: '.item',
columnWidth: 200
});
},
getStuff: function() {
$.ajax({
url: 'https://api.github.com/search/repositories',
method: 'GET',
data: {
q: this.term,
page: this.page(),
per_page: this.per_page()
}
}).then(function(r) {
this.items(r.items)
}.bind(this))
}
}
ko.applyBindings(vm);
.grid {
width: 400px;
}
.item {
margin-bottom: 2em;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://masonry.desandro.com/masonry.pkgd.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div>
<label>term:</label>
<input type="text" data-bind="value: term" />
</div>
<div>
<label>page:</label>
<input type="text" data-bind="value: page" />
</div>
<div>
<label>no of items:</label>
<input type="text" data-bind="value: per_page" />
</div>
<div>
<button data-bind="click: getStuff">get stuff</button>
<button data-bind="click: masonryize">masonryize</button>
</div>
<div class="grid" data-bind="masonry: {itemSelector: '.item', columnWidth: 200}, foreach: items">
<div class="item">
<p data-bind="text:name"></p>
<p data-bind="text:language"></p>
</div>
</div>