Skip to content

#Index within {{for}} or {{if}} blocks adds underscore to value (By Design!) #96

keithbeller opened this Issue Mar 22, 2012 · 6 comments

3 participants


Here is an example...

Example deleted, since the issue is addressed below...


I have the same issue with #index+1 (or just #index for that matter...) rendering with an underscore (and a much different value) in an {{if}}{{/if}} statement.

<tr rownumber="{{#index+1}}">{{:SomeData}}</tr>
{{if SomeMoreData != ""}}
<tr samerownumber="{{#index+1}}">{{:SomeMoreData}}</tr>

renders to:

<tr rownumber="1">data....</tr>
<tr samerownumber="_261">some more data...</tr>

Help? Shouldn't #index+1 render to the same value each time you use it?


Sorry I meant {{:#index}} and {{:#index+1}} in my example above


#index will be an integer when the view is one of a array of views (a view collection, if you will), which is what you get when you render against a data array, for example within a {{for}} tag: {{for someArray}}...{{:#index}}...{{/for}}.

Every 'block' tag renders its content as a subview of the containing view.

An {{if}} tag is a block tag, and renders a subview (or child view) of the containing view. That view is not part of a collection, and will not have an integer index.

But a {{for}} will render either a single child view, if its data is NOT an array, or it will render a view collection, and only in that case will the view(s) have integer indexes.

So if you put an {{if}} tag inside a {{for}} tag which is rendering an array, then you put {{:#index}} inside that, well, the {{:#index}} will render the index of the view it is in! And that is the view corresponding to the content of the {{if}} tag - which does not have an integer index. It's not an array of views, so why would it...

But what you wanted was the index of the containing view. Right. Well then step up to the parent view, and get its index. Write {{:#parent.index}}

this view is part of a view collection and has an index. {{if someExpression}} this is the view inside the if {{:#parent.index}} {{/if}}

In fact, when the data of a view is an array, it has a views property (the child views) which is an array, and each view has an integer index property.

When the data of a view is not an array (usually an object, but maybe some other value other than an array), then it has a views property for the various child views it may have (corresponding to nested templates, or block tags which it contains) and its view property is an object, not an array, with key-value pairs, typically {"_0":view1, ")2":view2 ...}. Each of those child views has an 'index' property which is the key, "_1" etc.

Does that make sense?

See also #97

@BorisMoore BorisMoore closed this Mar 23, 2012

@BorisMoore Thank you for the well-reasoned explanation. I changed my in-view references to #parent.index and all is well. Many thanks for this extremely valuable project. I am using jsrender pretty extensively on a couple of sites and the performance and ease of use is readily apparent!

@BorisMoore BorisMoore reopened this May 7, 2012

Reopened for discoverability, to document this design.


This issue has now been fixed in the latest commit: (pre beta commit counter: 8).
#key corresponds to what was #index, and #index is now the inherited integer index from what the nearest parent view that has an integer index.
So #index is now unchanged when you wrap {{:#index}} in and {{if}} block.

@BorisMoore BorisMoore closed this May 10, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.