Have a look at the following sample HTML. It is a simple KO foreach
binding and a button to add a new item to the observableArray
. The addition works fine and the new item shows up. However, the afterRender
method is never called - not after the initial binding and not after a new item is added (and rendered). Why?
Fiddle: http://jsfiddle.net/CQNm6
HTML
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script>
</head>
<body>
<div data-bind="foreach: data.things, afterRender: afterRenderTest">
<h1 data-bind="text: name"></h1>
</div>
<a href="JavaScript:void(0);" onclick="data.things.push({ name: ko.observable('New Thing') });">Add New Thing</a>
<script type="text/javascript">
var Thing = (function ()
{
function Thing(p_name)
{
this.name = ko.observable(p_name);
}
return Thing;
})();
var data =
{
things: ko.observableArray(
[
new Thing("Thing One"),
new Thing("Thing Two"),
new Thing("Thing Three")
])
};
function afterRenderTest(elements)
{
alert("Rendered " + elements.length + " elements.");
}
ko.applyBindings();
</script>
</body>
</html>
Your syntax is wrong because foreach
binding either take an array or an object where you specify the additional events, arguments.
From the documentaiton:
Pass the array that you wish to iterate over. The binding will output a section of markup for each entry.
Alternatively, pass a JavaScript object literal with a property called
data
which is the array you wish to iterate over. The object literal may also have other properties, such asafterAdd
orincludeDestroyed
...
So you need write:
<div data-bind="foreach: { data: data.things, afterRender: afterRenderTest }">
<h1 data-bind="text: name"></h1>
</div>
Demo JSFiddle.
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