Skip to content

#index doesn't work inside an {{if}} block in commit 22 #173

govis opened this Issue Dec 5, 2012 · 7 comments

2 participants

govis commented Dec 5, 2012

{{:#index}} doesn't seem to work anymore inside an {{if}} block:

There have been similar issues open in the past that are now closed: #107, #96, #97
The latest commit 22 seems to have affected this behaviour.


Yes this is mentioned in the commit notes:

View now has a type property, e.g. type="item"
Only "item" views have index properties, but to get the index from a nested
view use view.get("item").index.

I updated your jsfiddle:

You can write {{:#get('item').index}} from a nested template at any depth...

You can pass in the type of ancestor view you want: view.get(type) - allowed values: "item" | "array" | "data" | "root" | "top"
Default is "root" (The top level view with data, under the "top" view).

Hence view.get("item").index to get the index, view.get("array").data to get the array data, view.get("root").data to get the root data, etc...

govis commented Dec 5, 2012

Thanks Boris, I will give it a try.

Rendering or user interaction that is conditional or dependant upon the the item's index is probably going to be a very common use case and occur in most of the templates. What do you think of putting the logic of finding the closest item inside the #index itself to allow for the templates to be a bit cleaner?



The issue is that previously #index was getting updated on the "item" view when you used JsViews and inserted or removed an item from an observable collection. But the view.index property on child views, such as a nested if block was not getting updated. (And to do so would have been expensive in perf and code complexity). Hence the current design of not having a #index (which is short for view.index) on the non-item views such as the if block.

But the alternative of a 'getter' to get the index on the ancestor "item" view resolves that problem.

Currently the getter is view.get(type), which addresses this and a few other scenarios.

Now we could also add a specialized view.index() just for getting the view index, which would be equivalent to view.get("index").index. That would already help with making the template markup cleaner, right? But I wanted to let the get() API "settle" first, before deciding whether to add index()...

Does that make sense. I'm open to adding it sooner... not sure whether we need to yet...

govis commented Dec 6, 2012

Yes, makes total sense. I'm sure that the logic of propagating the item index down to all of it's child views would have been unnecessary complex and tedious to maintain.

I was thinking more along the lines of having a shortcut that would check if the current view is an item view then return it's index and otherwise simply forward the call to view.get("item").index. This would allow for consistent way of accessing the item’s index anywhere in the item's template.



Yes, the best we could do for a shortcut would be #index() - which is the declarative form of the view.index() shortcut I suggest above...

#index (without parens) is not possible

govis commented Dec 6, 2012

I think that #index() syntax should be good enough.

#index could be doable by using Object.defineProperty, but given the headaches that IE8 or below would give in that case, probably not worth it.

Please feel free to close the issue.


@BorisMoore BorisMoore added a commit that closed this issue Dec 10, 2012
@BorisMoore Commit counter 23. Several fixes and improvements. Main changes as fo…

#index will only work from item 'views', but #getIndex() now available from
nested {{if}} blocks etc. (fixes #173).

Fixes and improvements for associating resources (tags, helpers, converters)
with template. (See #170)

Sample test page for above nested resouces feature: nested-template-resources.html.

New feature for deep paths, which now allow a.b.c when a or b are null to
render an empty string, and not throw. Just set noerror=true. Updated sample
step-by-step/07_paths.html to show this, as well as the new comment tag:
{{!-- this is a comment --}}, and the use of aliases ~foo=expression for
providing access from nested templates without using #parent.parent.parent...

Continued improving compiled template output for ease of debugging. Set
$.views.settings.tryCatch=false; to cause errors thrown in compiled template
rendering to throw in the template, and facilitate debugging from there,
rather then rendering the error string and continuing... Example of this added
in nested-template-resources.html test page.

In commit 23 there is now a #getIndex() function which you can use when in a nested block, to get to the item index. It is actually a computed observable, so it will update if the index of the item changes (as a result of adding or removing sibling items). It is better to use #index when you are not in a nested template (e.g. {{if}} or {{for}}) since that will be better for perf...
Programmatically you can also do view.getIndex()

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.