Skip to content

Commit

Permalink
created location sibling option for the foreach binding
Browse files Browse the repository at this point in the history
  • Loading branch information
joeldart committed May 26, 2011
1 parent 700f6a9 commit 6b8a563
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 2 deletions.
16 changes: 16 additions & 0 deletions spec/templatingBehaviors.js
Expand Up @@ -418,5 +418,21 @@ describe('Templating', {

// ...but, because the old subscription should have been disposed automatically, there should only be one left
value_of(myModel.myObservable.getSubscriptionsCount()).should_be(1);
},

'Passing location of sibling renders the foreach template as a sibling of the node instead of a child': function () {
var myArray = new ko.observableArray([{ personName: "Bob" }, { personName: "Frank"}]);
ko.setTemplateEngine(new dummyTemplateEngine({ itemTemplate: "The item is [js: personName]" }));
testNode.innerHTML = "<div><div data-bind='template: { name: \"itemTemplate\", foreach: myCollection, location: \"sibling\" }'></div></div>";

ko.applyBindings({ myCollection: myArray }, testNode);
value_of(testNode.childNodes[0].innerHTML.toLowerCase().replace("\r\n", "")).should_be("<div data-bind='template: { name: \"itemtemplate\", foreach: mycollection, location: \"sibling\" }'></div><div>the item is bob</div><div>the item is frank</div>");

myArray.push({personName: "Steve" });
value_of(testNode.childNodes[0].innerHTML.toLowerCase().replace("\r\n", "")).should_be("<div data-bind='template: { name: \"itemtemplate\", foreach: mycollection, location: \"sibling\" }'></div><div>the item is bob</div><div>the item is frank</div><div>the item is steve</div>");
myArray.splice(1, 0, {personName: "another"});
value_of(testNode.childNodes[0].innerHTML.toLowerCase().replace("\r\n", "")).should_be("<div data-bind='template: { name: \"itemtemplate\", foreach: mycollection, location: \"sibling\" }'></div><div>the item is bob</div><div>the item is another</div><div>the item is frank</div><div>the item is steve</div>");
myArray.splice(0,0, {personName: "initial"});
value_of(testNode.childNodes[0].innerHTML.toLowerCase().replace("\r\n", "")).should_be("<div data-bind='template: { name: \"itemtemplate\", foreach: mycollection, location: \"sibling\" }'></div><div>the item is initial</div><div>the item is bob</div><div>the item is another</div><div>the item is frank</div><div>the item is steve</div>");
}
})
10 changes: 9 additions & 1 deletion src/binding/editDetection/arrayToDomNodeChildren.js
Expand Up @@ -40,6 +40,12 @@
var nodesToDelete = [];
var nodesAdded = [];
var insertAfterNode = null;
var originalNode;
if (options.location === "sibling") {
insertAfterNode = domNode;
originalNode = domNode;
domNode = domNode.parentNode;
}
for (var i = 0, j = editScript.length; i < j; i++) {
switch (editScript[i].status) {
case "retained":
Expand Down Expand Up @@ -118,7 +124,9 @@
if (node.element.parentNode)
node.element.parentNode.removeChild(node.element);
});

if (options.location === "sibling") {
domNode = originalNode;
}
// Store a copy of the array items we just considered so we can difference it next time
ko.utils.domData.set(domNode, "setDomNodeChildrenFromArrayMapping_lastMappingResult", newMappingResult);
}
Expand Down
2 changes: 1 addition & 1 deletion src/templating/templating.js
Expand Up @@ -113,7 +113,7 @@
var templateSubscription;
if (typeof bindingValue['foreach'] != "undefined") {
// Render once for each data point
templateSubscription = ko.renderTemplateForEach(templateName, bindingValue['foreach'] || [], { 'templateOptions': bindingValue['templateOptions'], 'afterAdd': bindingValue['afterAdd'], 'beforeRemove': bindingValue['beforeRemove'], 'includeDestroyed': bindingValue['includeDestroyed'], 'afterRender': bindingValue['afterRender'] }, element);
templateSubscription = ko.renderTemplateForEach(templateName, bindingValue['foreach'] || [], { 'templateOptions': bindingValue['templateOptions'], 'afterAdd': bindingValue['afterAdd'], 'beforeRemove': bindingValue['beforeRemove'], 'includeDestroyed': bindingValue['includeDestroyed'], 'afterRender': bindingValue['afterRender'], 'location': bindingValue['location'] }, element);
}
else {
// Render once for this single data point (or use the viewModel if no data was provided)
Expand Down

0 comments on commit 6b8a563

Please sign in to comment.