diff --git a/spec/bindingAttributeBehaviors.js b/spec/bindingAttributeBehaviors.js index 1291c53ab..9504ccef3 100644 --- a/spec/bindingAttributeBehaviors.js +++ b/spec/bindingAttributeBehaviors.js @@ -621,4 +621,9 @@ describe('Binding attribute syntax', function() { ko.applyBindings({ callback: function () { callbacks++; } }, testNode); expect(callbacks).toEqual(0); }); + + it('Should ignore (and not throw an error) for a null afterRender callback', function () { + testNode.innerHTML = "
"; + ko.applyBindings({}, testNode); + }); }); diff --git a/spec/bindingDependencyBehaviors.js b/spec/bindingDependencyBehaviors.js index 1fa714ab0..4d5513fef 100644 --- a/spec/bindingDependencyBehaviors.js +++ b/spec/bindingDependencyBehaviors.js @@ -289,6 +289,38 @@ describe('Binding dependencies', function() { expect(callbacks).toEqual(2); }); + it('Should always use the latest value of an afterRender callback', function () { + ko.bindingHandlers.test = { + init: function() { + return { controlsDescendantBindings: true }; + }, + update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { + var innerContext = bindingContext.createChildContext({childprop: ko.utils.unwrapObservable(valueAccessor())}); + element.innerHTML = ""; + ko.applyBindingsToDescendants(innerContext, element); + } + }; + + var callbackSpy1 = jasmine.createSpy('callbackSpy1'), + callbackSpy2 = jasmine.createSpy('callbackSpy2'), + vm = { + observable: ko.observable('value'), + callback: callbackSpy1 + }; + + testNode.innerHTML = "
"; + ko.applyBindings(vm, testNode); + expect(callbackSpy1).toHaveBeenCalled(); + + callbackSpy1.reset(); + vm.callback = callbackSpy2; + + vm.observable('new value'); + expect(testNode.childNodes[0]).toContainText('new value'); + expect(callbackSpy1).not.toHaveBeenCalled(); + expect(callbackSpy2).toHaveBeenCalled(); + }); + describe('Observable view models', function() { it('Should update bindings (including callbacks)', function() { var vm = ko.observable(), clickedVM; diff --git a/src/binding/bindingAttributeSyntax.js b/src/binding/bindingAttributeSyntax.js index 72a3c27d6..acb95fc9d 100755 --- a/src/binding/bindingAttributeSyntax.js +++ b/src/binding/bindingAttributeSyntax.js @@ -235,12 +235,15 @@ var afterRender = ko.utils.domData.get(elementOrVirtualElement, afterRenderCallbackDomDataKey); if (afterRender) { - var nodes = ko.virtualElements.childNodes(elementOrVirtualElement); - if (nodes.length) { - ko.dependencyDetection.ignore(function () { - evaluateValueAccessor(afterRender)(nodes, ko.dataFor(nodes[0])); - }); - } + ko.dependencyDetection.ignore(function () { + afterRender = evaluateValueAccessor(afterRender); + if (afterRender) { + var nodes = ko.virtualElements.childNodes(elementOrVirtualElement); + if (nodes.length) { + afterRender(nodes, ko.dataFor(nodes[0])); + } + } + }); } } }