Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Ember.js View Context Change

View Context Changes

The rules for how Ember.js evaluates Handlebars templates have recently changed, and you may need to update your application's templates to ensure they continue working..

Template Contexts

Remember that a template is always evaluated against a context object. When you render a template, values are looked up from that object. For example:

Hello, {{firstName}} {{lastName}}!

The firstName and lastName properties are looked up on the context object for this template. If our context was the following object:

  firstName: "Clark",
  lastName: "Gable"

The template would render:

Hello, Clark Gable!

Inside a template, helpers can alter the context inside blocks. Two helpers that change context are {{#with}} and {{#each}}, which change the context to the specified object or to each item in an enumerable, respectively.

Previously, Ember.js' {{#view}} helper would also change the context of the template inside it. For example, imagine we changed the above example to be wrapped inside a {{#view}} helper, so it read like this:

{{#view App.WelcomeView}}Hello, {{firstName}} {{lastName}}!{{/view}}

You may be surprised to learn that this would render the string "Hello, ", because it is trying to look up the firstName and lastName properties on the view instead of the parent context!

In more recent versions of Ember.js, this will now work as expected and render Hello, Clark Gable!. If you really want to refer to a property of the view, you can use the view keyword to lookup a value on the current scope's view:

{{#view App.WelcomeView}}Hello, {{firstName}} {{lastName}}! {{view.currentTime}}{{/view}}


// Before:
{{#each App.photosController}}
  Photo Title: {{title}}
  {{#view App.InfoView contentBinding="this"}}

// After:
{{#each App.photosController}}
  Photo Title: {{title}}
  {{#view App.InfoView}}

One thing that wasn't clear to me until I poked around a bit is that you seem to always have to use the view keyword to access the view object. The gist implies (to me) that you only have to use the view keyword with {{#with}} or {{#each}}.

Here is a simple example that I find a bit counterintuitive:

App.MyView = Ember.View.extend({
  foo: 'bar'

{{#view App.MyView}}
  foo: {{foo}}<br> {{}}

Here it is in a JSFiddle.

Am I missing something here? You say [emphasis mine] "you may need to update your application's templates to ensure they continue working", but I can't imagine anyone not having to change every single template in their app because of this. If that's the case, so be it, but I want to make sure I actually understand the implications of it.

tdreyno commented Jun 7, 2012

This seems to break my custom CollectionView because this only works with #each but not #collection, am I doing something wrong?


tomdale commented Jun 8, 2012

@tdreyno These changes should definitely work with CollectionView. Inside your item view's template, view should reference the item view, and view.content should reference the item in your content array.


tomdale commented Jun 8, 2012

@adamlogic Yes, most templates will need to change because of this. I suppose we were using marketing terminology to soften the blow; sorry about that. :P

In our applications, these changes have allowed us to significantly reduce the verbosity of our templates, but we did need to go through and audit all of them.

Can you clarify: Is this only for {{#view}} helper and inline templates? Or does this apply to {{view}} with templates in a different file as well?


tomdale commented Jun 29, 2012

@psndcsrv This applies to templates in a different file as well.

workmanw commented Jul 3, 2012

I recently went through the process of updating our app to support the "view context changes" to handlebars. I put together some feedback on this change and how it impacted us. Here it is:

I want to know if ember is ready for production Iam really confused wit all those changes?!

The topic should appear in websites doc, otherwise confusing a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment