Based on the suggestion give here, and the information given here on how to make a custom bindingHandler for a forEach, I decided to attempt to write my own custom binding for a forEach and Masonry.
Because the elements are added on the fly the redrawing and moving around of elements to fill the space doesn't occur. So, this functionality needed to be moved after the elements have been rendered or called after each item has been added.
Here is my bindingHandler
ko.bindingHandlers.masonry = {
init: function (element, valueAccessor, allBindingsAccessor) {
var $element = $(element),
originalContent = $element.html();
$element.data("original-content", originalContent);
//var msnry = new Masonry($element);
return { controlsDescendantBindings: true }
},
update: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
//get the list of items
items = value.items(),
//get a jQuery reference to the element
$element = $(element),
//get the current content of the element
elementContent = $element.data("original-content");
$element.html("");
var container = $element[0];
var msnry = new Masonry(container);
for (var index = 0; index < items.length; index++) {
(function () {
//get the list of items
var item = ko.utils.unwrapObservable(items[index]),
$childElement = $(elementContent);
ko.applyBindings(item, $childElement[0]);
//add the child to the parent
$element.append($childElement);
msnry.appended($childElement[0]);
})();
msnry.layout();
msnry.bindResize();
}
}
};
and the HTML implementing the handler.
<div id="criteriaContainer" data-bind="masonry: { items: SearchItems.Items }">
<div class="searchCriterion control-group">
<label class="control-label" data-bind="text: Description"></label>
<div class="controls">
<input type="hidden" data-bind="value: Value, select2: { minimumInputLength: 3, queryUri: SearchUri(), placeholder: Placeholder(), allowClear: true }" style="width: 450px">
</div>
<p data-bind="text: Value"></p>
</div>
</div>
When this shows up on the page It stacks all if the elements rendered via the append method right on top of each other.
You can see in my bindingHandler I am calling bindResize as well as layout(), neither of which seem to be having any effect.
Here's a screenshot of what it looks like in the UI.