Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

container offset #117

Closed
wants to merge 2 commits into from

3 participants

@antis

Added template.containerOffset Support.

Here is Example:
http://jsfiddle.net/Xf2g4/

@andreialecu

+1 for this, it is pretty powerful and it would allow correctly ordering elements within template containers.

For example, imagine a table. It is good practice to order the elements within it in the order of thead/tbody/tfoot. If the template is for tbody and the table already provides thead and tfoot, this pull request would allow this scenario:

<table data-bind="template: ...">
<thead>
... headers here
</thead>

... template should render here ...
<tfoot>
...
</tfoot>
</table>

However, note that in 1.3.0 this behavior is broken due to: #165

@SteveSanderson

Thanks for submitting this. Could you clarify what the use case is for adjusting the container offset? I read the comment from andreialecu, but I'm not sure why you wouldn't just reference the template at the location you want to render it, for example:

<table>
    <thead>
        ... headers here
    </thead>
    <tbody data-bind="template: ...."></tbody>
    <tfoot>
        ...
    </tfoot>

or even

<table>
    <thead>
        ... headers here
    </thead>
    <!-- ko template: .... -->Template may output a <tbody> elem, which will go here<!-- /ko template -->
    <tfoot>
        ...
    </tfoot>

@andreialecu

It is legal in HTML to have multiple tbody elements within a table, something that would only be possible using a 'foreach' template binding on the table because you can't put <tbody> elements in anything else other than <table>

<table data-bind="template, foreach, containerindex: 1">
<thead>
</thead>
<!-- rendered tbodies start here -->
<tbody>
</tbody>
<tbody>
</tbody>
<tbody>
</tbody>

<tfoot>
</tfoot>
</table>

The comment based templating new to 1.3.0 works because it allows foreach without a wrapper element, and it is what I'm using as a workaround now. Similar to your second example, but also specifying a foreach.

@SteveSanderson

Great - are you happy that the comment-based "foreach" syntax covers this requirement? If so, I'll close this.

@andreialecu

The comment approach fits my needs. But I'm not sure whether antis had other things in mind with this pull request. It does allow one to programatically change where the template gets rendered, while the comment based approach does not.

He doesn't seem active here any longer. If you can't think of a reason why programmatic control over where the template is rendered makes sense then I guess you can close. :)

@SteveSanderson

Thanks for confirming.

I'd be happy to include the containerOffset feature if there was a clear use-case, but in light of the new KO 1.3 syntaxes I'm not sure what the use case would be. So, I'll close this now, but either of you could re-open it with more information if you wish.

Thanks again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 16, 2011
  1. @antis
  2. @antis
This page is out of date. Refresh to see the latest.
View
10 src/binding/editDetection/arrayToDomNodeChildren.js
@@ -1,4 +1,3 @@
-
(function () {
// Objective:
// * Given an input array, a container DOM node, and a function from array elements to arrays of DOM nodes,
@@ -81,8 +80,15 @@
value: editScript[i].value
});
if (insertAfterNode == null) {
+ if (options.containerOffset != undefined) {
+ var realContainerOffset = options.containerOffset >= 0 ?
+ options.containerOffset :
+ Math.max(0, domNode.childNodes.length - (-options.containerOffset));
+
+
+ domNode.insertBefore(node, ((domNode.childNodes.length > realContainerOffset) ? domNode.childNodes[realContainerOffset] : null ));
+ } else if (domNode.firstChild)
// Insert at beginning
- if (domNode.firstChild)
domNode.insertBefore(node, domNode.firstChild);
else
domNode.appendChild(node);
View
3  src/templating/templating.js
@@ -1,4 +1,3 @@
-
(function () {
var _templateEngine;
ko.setTemplateEngine = function (templateEngine) {
@@ -113,7 +112,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'] , 'containerOffset': bindingValue['containerOffset']}, element);
}
else {
// Render once for this single data point (or use the viewModel if no data was provided)
Something went wrong with that request. Please try again.