I am having some problems getting KnockoutJs beforeRemove and afterAdd handlers to fire.
This is the relevant code fragment
function viewModel(list) {
var self = this;
this.items = ko.observableArray(list);
this.removeItem = function(item) {
self.items.remove(item);
}
this.removeFirst = function() {
self.removeItem(self.items()[0]);
};
this.onRemove = function(elements) {
console.log("Updating");
$(elements).addClass('transition-out');
};
}
ko.applyBindings(new viewModel(items));
And this markup
<button data-bind="click: removeFirst">Remove first</button>
<ul data-bind='foreach: items, beforeRemove: onRemove'>
<li data-bind="text: name, click: $parent.removeItem"></li>
</ul>
I am seeing list updates but the onRemove
handler is never fired.
I've created a JSFiddle to illustrate the problem.
Thanks,
Gene
The $data variable is a built-in variable used to refer to the current object being bound. In the example this is the one of the elements in the viewModel.
Purpose. The foreach binding duplicates a section of markup for each entry in an array, and binds each copy of that markup to the corresponding array item. This is especially useful for rendering lists or tables.
ko. dataFor(element) - returns the data that was available for binding against the element. ko. contextFor(element) - returns the entire binding context that was available to the DOM element.
If you want to access the array by index, you need to evaluate the observable first using () . If you want the value binding to work two-ways (i.e.: not only set it initially, but also update the values in your viewmodel after a change), you'll have to bind them to ko.
The syntax that you want to use looks like:
data-bind='foreach: { data: items, beforeRemove: onRemove }'
beforeRemove
is an option that is accepted by the foreach
(and ultimately the template
) binding. It was being treated as a separate binding in the way that you were specifying it. If a binding does not exist, then it is ignored (some binding are accessed via allBindingsAccessor, so KO wouldn't know that and doesn't throw an error).
Also, the function will get called once for each node in your "template". In your case it will be a text node, the li
, and another text node. If you want to ignore the text nodes, then check that the element's (first argument) nodeType is 1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With