Ember.js and handlebars each helper, with subviews

I'm trying to use the view helper inside the {{#each}} template blocks without using global paths (my controllers create and destroy their own views).

Examples. Given the view using the myList array property and the itemButton child view:

It will work

<script type="text/x-handlebars" name="my-list-view"> {{#each myList}} <!-- App.myListView.myList --> {{view App.myListView.itemButton}} {{title}} {{/each}} </script> 


It will not be:

 <script type="text/x-handlebars" name="my-list-view"> {{itemButton}} <!-- works fine outside the each --> {{#each myList}} {{view itemButton}} {{title}} <!-- itemButton view not found --> {{/each}} </script> 

It seems I can’t access the parent view from each view helper (or actually access anything other than the properties of the repeating objects).

Hacker workarounds I came up with:

  • Add the view that I want to use for the elements I'm repeating.

or

  • Creating a View Collection in App.myListView
  • Create an itemViewClass in this collection view class
  • Move itemButton view inside itemViewClass
  • Replace {{#each}} with {{#collection}}

or

  • Create your own descriptor helper for iteration.

Both of these parameters seem terrible. Of course, there is a better alternative than creating 2 new classes (and nesting 4 types in depth) to iterate over the list. Is there a helper helper that I can use instead?


Workarounds

Option # 1: changing the content array

http://jsfiddle.net/FQEZq/3/ Disadvantages: the need to add a view to an instance of each model for iteration only.

Option # 2: View a Custom Collection

http://jsfiddle.net/ST24Y/1/ Disadvantages: now you have two additional views that you don't need / need, and less control over the markup. Links from the child view to the parent instance now require parentView.parentView.parentView.

+7
source share
2 answers

#each too limited for your requirements. You can make it work if you want to use the global path to the view you want to embed in #each . Otherwise, your approach to presenting your collection is best. Adding a view to a model instance can cause your application design to become violent, so I wouldn’t.

One idea to keep your templates clean is to use Ember.View properties, such as:

  • collectionView - Return the closest ancestor that is Ember.CollectionView
  • itemView - Return the closest ancestor that is a direct descendant of Ember.CollectionView
  • contentView - Return the closest ancestor that has the property.
+3
source

The big thing here is the options.

Hooks for how you want to use the template are available. It:

 <-- render templates/name.js --> {{partial 'name'}} <-- render views/name.js --> {{view 'name'}} <-- render views/name1.js with controllers/name2.js --> {{render 'name1' 'name2'}} <!-- see also: --> {{output}} {{output 'named'}} {{yield}} 

A sample version of your initial template showing 4 different options:

 <script type='text/x-handlebars' data-template-name='my-list-view'> <h2>Option 1</h2> {{#each myList}} {{! the 2nd parameter will look for itemButtonController }} {{render 'itembutton' itemButton}} {{/each}} <h2>Option 2</h2> {{#each myList}} {{! using an Ember Component }} {{#item-button }} some static text OR {{dynamic}} {{/item-button}} <!-- in component/item-button.hbs add {{yield}} for where you want the static content to output --> {{/each}} <h2>Option 3</h2> {{#each myList}} {{! if the button is to be a link }} {{#link-to 'route' parameter tagName='button' classNames='btn'}} {{title}} {{/link-to}} {{/each}} <h2>Option 4</h2> <p>Ludicrous example showing almost every reference option!</p> {{! focus the context on subview data }} {{#with someArrayOrCollectionOfView}} {{! prepend type to add context - here returning back up to this view properties }} {{#each view.myList}} {{! this is equivalent to someArrayOrCollectionOfView[x].name }} {{name}} {{! a button that hooks in route, model, and 2 controllers, and applies a target for the output when clicked }} {{#link-to 'page' controllers.page.nextPage target='outlet' tagName='button' disabledWhen=controller.disableNext }} {{model.buttonName}} {{/link-to}} {{/each}} {{/with}} {{! generic default target (automatic) }} {{outlet}} {{! example of a named target }} {{outlet 'footerlinks'}} </script> 

Mmmm ... link for further reading: Ember.Handlebars.helpers

0
source

All Articles