Skip to content

Commit

Permalink
afterRender should work when used with virtual element
Browse files Browse the repository at this point in the history
  • Loading branch information
mbest committed Oct 4, 2017
1 parent bc398f0 commit 0003397
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
22 changes: 20 additions & 2 deletions spec/defaultBindings/withBehaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "<div data-bind='with: someItem, afterRender: callback'><span data-bind='text: childprop'></span></div>";
Expand All @@ -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 = "<!-- ko with: someItem, afterRender: callback --><span data-bind='text: childprop'></span><!-- /ko -->";
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 = "<div data-bind='with: someItem, afterRender: callback'><span data-bind='text: childprop'></span></div>";
var someItem = ko.observable({ childprop: 'child' }),
Expand Down
11 changes: 6 additions & 5 deletions src/binding/defaultBindings/ifIfnotWith.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,26 @@ 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) :
ifCondition.isActive() ?
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);
Expand Down

0 comments on commit 0003397

Please sign in to comment.