我正在使用knockoutjs和masonry并创建了一个自定义的淘汰赛绑定处理程序,以将砌体应用于html元素。
我想要应用砌体的容器使用knockout foreach
绑定动态注入内容。
我遇到的问题是在砌体容器动态更新后,自行应用砌体。
在代码段示例中,如果您单击 masonryize 按钮,它将销毁砌体容器并重新应用mansonry,如何将此行为引入我的绑定处理程序?< / p>
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>
答案 0 :(得分:2)
在masonsy容器更新后,这取决于你的意思。你的意思是调整大小或加载新项目?如果你知道容器何时需要更新,你可以这样做:
ko.bindingHandlers.masonry = {
init: function(element, valueAccessor, allBindingsAccessor) {
ko.computed(function () {
var options = ko.unwrap(valueAccessor());
ko.unwrap(allBindingsAccessor().masonryUpdater);
$(element).masonry('destroy');
$(element).masonry(options);
}, null, disposeWhenNodeIsRemoved: element);
}
}
// ...
vm.masonryUpdater = ko.observable();
// When you need to update just run
vm.masonryUpdater.valueHasMutated();
并像这样应用你的绑定:
<div class="grid" data-bind="masonry: {itemSelector: '.item', columnWidth: 200}, masonryUpdater: masonryUpdater, foreach: items">
<div class="item">
<p data-bind="text:name"></p>
<p data-bind="text:language"></p>
</div>
</div>
所以这里发生了什么:
allBindingsAccessor().masonryUpdater
的订阅。这样,无论何时更新计算,我们创建都将重新评估并重新应用砌体。vm.masonryUpdater.valueHasMutated();
这种看起来像伏都教,加上有些人可能会说我们正在利用副作用。好吧也许只是一点点。从好的方面来说,我们为自己制作的东西非常简单。需要完成的所有事情都是在计算之外执行的,所有需要依赖的内容或计算内部的更新。调试和保存数据以供以后使用也更容易。
这里将详细介绍http://www.knockmeout.net/2012/06/knockoutjs-performance-gotcha-3-all-bindings.html