动态更新后自动在knockout绑定处理程序中应用masonry

我正在使用带有砌体的 knockoutjs并创建了一个自定义的敲除绑定处理程序,以将砌体应用于html元素。

我想要应用砌体的容器使用knockout的foreach绑定动态注入它的内容。

我遇到的问题是在砌筑容器动态更新后,自行应用砌体。

在代码段示例中,如果单击masonryize按钮,则会破坏砌体容器并重新应用mansonry,如何将此行为添加到我的绑定处理程序中?

 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; } 
    

在masonsy容器更新后,这取决于你的意思。 你的意思是resize或者加载新项目吗? 如果您知道容器何时需要更新,您可以这样做:

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

并像这样应用你的绑定:

 

那么这里发生了什么:

  1. 我们通过阅读它来创建对可观察的allBindingsAccessor().masonryUpdater的订阅。 这样,无论何时更新计算,我们创建都将重新评估并重新应用砌体。
  2. 为了告诉我们我们的观察结果发生了变化,我们称之为vm.masonryUpdater.valueHasMutated();
  3. 删除网格元素后,将安全地处理计算结果

这种看起来像伏都教,加上有些人可能会说我们正在利用副作用。 好吧也许只有一点点。 从好的方面来说,我们为自己制作的东西非常简单。 需要完成的所有事情都是在计算之外执行的,所有需要依赖的内容或计算内的更新。 调试和保存数据以供以后使用也更容易。

这里将详细介绍http://www.knockmeout.net/2012/06/knockoutjs-performance-gotcha-3-all-bindings.html