diff --git a/spec/defaultBindings/withBehaviors.js b/spec/defaultBindings/withBehaviors.js
index cf80eef57..a9df2293b 100644
--- a/spec/defaultBindings/withBehaviors.js
+++ b/spec/defaultBindings/withBehaviors.js
@@ -224,7 +224,6 @@ describe('Binding: With', function() {
model.items()[0].x(10);
expect(testNode).toContainText("Total: 25");
});
-});
it('Should call an afterRender callback function and not cause updates if an observable accessed in the callback is changed', function () {
testNode.innerHTML = "
";
@@ -240,12 +239,31 @@ describe('Binding: With', function() {
// Update callback observable and check that the binding wasn't updated
callbackObservable(2);
expect(testNode.childNodes[0]).toContainText('child');
- // Update the observableArray and verify that the binding is now updated
+ // Update the observable and verify that the binding is now updated
someItem({ childprop: 'new child' });
expect(testNode.childNodes[0]).toContainText('new child');
expect(callbacks).toEqual(2);
});
+ it('Should call an afterRender callback function when bound to a virtual element', function () {
+ testNode.innerHTML = "";
+ var someItem = ko.observable({ childprop: 'child' }),
+ callbacks = 0;
+ var callback = function (nodes, data) {
+ expect(nodes.length).toEqual(1);
+ expect(nodes[0]).toEqual(testNode.childNodes[1]);
+ expect(data.childprop).toEqual(someItem().childprop);
+ callbacks++;
+ };
+ ko.applyBindings({ someItem: someItem, callback: callback }, testNode);
+ expect(callbacks).toEqual(1);
+
+ // Update the observable and verify that the binding is now updated
+ someItem({ childprop: 'new child' });
+ expect(testNode.childNodes[1]).toContainText('new child');
+ expect(callbacks).toEqual(2);
+ });
+
it('Should not call an afterRender callback function when data gets cleared', function () {
testNode.innerHTML = "
";
var someItem = ko.observable({ childprop: 'child' }),
diff --git a/src/binding/defaultBindings/ifIfnotWith.js b/src/binding/defaultBindings/ifIfnotWith.js
index f68e747dc..3d1a39aff 100755
--- a/src/binding/defaultBindings/ifIfnotWith.js
+++ b/src/binding/defaultBindings/ifIfnotWith.js
@@ -10,16 +10,17 @@ function makeWithIfBinding(bindingKey, isWith, isNot) {
ko.computed(function() {
var rawWithValue = isWith && ko.utils.unwrapObservable(valueAccessor()),
shouldDisplay = isWith ? !!rawWithValue : ifCondition(),
- isFirstRender = !savedNodes;
+ isFirstRender = !savedNodes,
+ renderNodes;
// Save a copy of the inner nodes on the initial update, but only if we have dependencies.
if (isFirstRender && ko.computedContext.getDependenciesCount()) {
- savedNodes = ko.utils.cloneNodes(ko.virtualElements.childNodes(element), true /* shouldCleanNodes */);
+ savedNodes = ko.utils.cloneNodes(renderNodes = ko.virtualElements.childNodes(element), true /* shouldCleanNodes */);
}
if (shouldDisplay) {
if (!isFirstRender) {
- ko.virtualElements.setDomNodeChildren(element, ko.utils.cloneNodes(savedNodes));
+ ko.virtualElements.setDomNodeChildren(element, renderNodes = ko.utils.cloneNodes(savedNodes));
}
var newContext = isWith ?
bindingContext['createChildContext'](typeof rawWithValue == "function" ? rawWithValue : valueAccessor) :
@@ -27,8 +28,8 @@ function makeWithIfBinding(bindingKey, isWith, isNot) {
bindingContext['extend'](function() { ifCondition(); return null; }) :
bindingContext;
ko.applyBindingsToDescendants(newContext, element);
- if (element.childNodes.length && allBindings.has('afterRender')) {
- ko.dependencyDetection.ignore(allBindings.get('afterRender'), null, [element.childNodes, newContext['$data']]);
+ if (allBindings.has('afterRender')) {
+ ko.dependencyDetection.ignore(allBindings.get('afterRender'), null, [renderNodes || ko.virtualElements.childNodes(element), newContext['$data']]);
}
} else {
ko.virtualElements.emptyNode(element);