Ember.Handlebars.helpers Class

Show:

_triageMustache

(property, fn) String private

Parameters:

property String
Property/helperID to triage
fn Function
Context to provide for rendering

Returns:

String
HTML string

action

(actionName, context, options)

The {{action}} helper registers an HTML element within a template for DOM event handling and forwards that interaction to the view's controller or supplied target option (see 'Specifying a Target').

If the view's controller does not implement the event, the event is sent to the current route, and it bubbles up the route hierarchy from there.

User interaction with that element will invoke the supplied action name on the appropriate target.

Given the following Handlebars template on the page

1
2
3
4
5
<script type="text/x-handlebars" data-template-name='a-template'>
  <div {{action anActionName}}>
    click me
  </div>
</script>

And application code

1
2
3
4
5
6
7
8
9
10
11
AController = Ember.Controller.extend({
  anActionName: function() {}
});

AView = Ember.View.extend({
  controller: AController.create(),
  templateName: 'a-template'
});

aView = AView.create();
aView.appendTo('body');

Will results in the following rendered HTML

1
2
3
4
5
<div class="ember-view">
  <div data-ember-action="1">
    click me
  </div>
</div>

Clicking "click me" will trigger the anActionName method of the AController. In this case, no additional parameters will be passed.

If you provide additional parameters to the helper:

1
<button {{action 'edit' post}}>Edit</button>

Those parameters will be passed along as arguments to the JavaScript function implementing the action.

Event Propagation

Events triggered through the action helper will automatically have .preventDefault() called on them. You do not need to do so in your event handlers.

To also disable bubbling, pass bubbles=false to the helper:

1
<button {{action 'edit' post bubbles=false}}>Edit</button>

If you need the default handler to trigger you should either register your own event handler, or use event methods on your view class. See Ember.View 'Responding to Browser Events' for more information.

Specifying DOM event type

By default the {{action}} helper registers for DOM click events. You can supply an on option to the helper to specify a different DOM event name:

1
2
3
4
5
<script type="text/x-handlebars" data-template-name='a-template'>
  <div {{action anActionName on="doubleClick"}}>
    click me
  </div>
</script>

See Ember.View 'Responding to Browser Events' for a list of acceptable DOM event names.

NOTE: Because {{action}} depends on Ember's event dispatch system it will only function if an Ember.EventDispatcher instance is available. An Ember.EventDispatcher instance will be created when a new Ember.Application is created. Having an instance of Ember.Application will satisfy this requirement.

Specifying whitelisted modifier keys

By default the {{action}} helper will ignore click event with pressed modifier keys. You can supply an allowedKeys option to specify which keys should not be ignored.

1
2
3
4
5
<script type="text/x-handlebars" data-template-name='a-template'>
  <div {{action anActionName allowedKeys="alt"}}>
    click me
  </div>
</script>

This way the {{action}} will fire when clicking with the alt key pressed down.

Specifying a Target

There are several possible target objects for {{action}} helpers:

In a typical Ember application, where views are managed through use of the {{outlet}} helper, actions will bubble to the current controller, then to the current route, and then up the route hierarchy.

Alternatively, a target option can be provided to the helper to change which object will receive the method call. This option must be a path path to an object, accessible in the current context:

1
2
3
4
5
<script type="text/x-handlebars" data-template-name='a-template'>
  <div {{action anActionName target="MyApplication.someObject"}}>
    click me
  </div>
</script>

Clicking "click me" in the rendered HTML of the above template will trigger the anActionName method of the object at MyApplication.someObject.

If an action's target does not implement a method that matches the supplied action name an error will be thrown.

1
2
3
4
5
<script type="text/x-handlebars" data-template-name='a-template'>
  <div {{action aMethodNameThatIsMissing}}>
    click me
  </div>
</script>

With the following application code

1
2
3
4
5
6
7
8
AView = Ember.View.extend({
  templateName; 'a-template',
  // note: no method 'aMethodNameThatIsMissing'
  anActionName: function(event) {}
});

aView = AView.create();
aView.appendTo('body');

Will throw Uncaught TypeError: Cannot call method 'call' of undefined when "click me" is clicked.

Additional Parameters

You may specify additional parameters to the {{action}} helper. These parameters are passed along as the arguments to the JavaScript function implementing the action.

1
2
3
4
5
6
7
<script type="text/x-handlebars" data-template-name='a-template'>
  {{#each person in people}}
    <div {{action edit person}}>
      click me
    </div>
  {{/each}}
</script>

Clicking "click me" will trigger the edit method on the current view's controller with the current person as a parameter.

Parameters:

actionName String
context Object
options Hash

bind

(property, fn) String private

Parameters:

property String
Property to bind
fn Function
Context to provide for rendering

Returns:

String
HTML string

bindAttr

(options) String

bindAttr allows you to create a binding between DOM element attributes and Ember objects. For example:

1
<img {{bindAttr src="imageUrl" alt="imageTitle"}}>

The above handlebars template will fill the <img>'s src attribute will the value of the property referenced with "imageUrl" and its alt attribute with the value of the property referenced with "imageTitle".

If the rendering context of this template is the following object:

1
2
3
4
{
  imageUrl: 'http://lolcats.info/haz-a-funny',
  imageTitle: 'A humorous image of a cat'
}

The resulting HTML output will be:

1
<img src="http://lolcats.info/haz-a-funny" alt="A humorous image of a cat">

bindAttr cannot redeclare existing DOM element attributes. The use of src in the following bindAttr example will be ignored and the hard coded value of src="/failwhale.gif" will take precedence:

1
<img src="/failwhale.gif" {{bindAttr src="imageUrl" alt="imageTitle"}}>

bindAttr and the class attribute

bindAttr supports a special syntax for handling a number of cases unique to the class DOM element attribute. The class attribute combines multiple discreet values into a single attribute as a space-delimited list of strings. Each string can be:

  • a string return value of an object's property.
  • a boolean return value of an object's property
  • a hard-coded value

A string return value works identically to other uses of bindAttr. The return value of the property will become the value of the attribute. For example, the following view and template:

1
2
3
4
5
  AView = Ember.View.extend({
    someProperty: function(){
      return "aValue";
    }.property()
  })
1
<img {{bindAttr class="view.someProperty}}>

Result in the following rendered output:

1
<img class="aValue">

A boolean return value will insert a specified class name if the property returns true and remove the class name if the property returns false.

A class name is provided via the syntax somePropertyName:class-name-if-true.

1
2
3
AView = Ember.View.extend({
  someBool: true
})
1
<img {{bindAttr class="view.someBool:class-name-if-true"}}>

Result in the following rendered output:

1
<img class="class-name-if-true">

An additional section of the binding can be provided if you want to replace the existing class instead of removing it when the boolean value changes:

1
<img {{bindAttr class="view.someBool:class-name-if-true:class-name-if-false"}}>

A hard-coded value can be used by prepending : to the desired class name: :class-name-to-always-apply.

1
<img {{bindAttr class=":class-name-to-always-apply"}}>

Results in the following rendered output:

1
<img class="class-name-to-always-apply">

All three strategies - string return value, boolean return value, and hard-coded value – can be combined in a single declaration:

1
<img {{bindAttr class=":class-name-to-always-apply view.someBool:class-name-if-true view.someProperty"}}>

Parameters:

options Hash

Returns:

String
HTML string

boundIf

(property, fn) String private

Parameters:

property String
Property to bind
fn Function
Context to provide for rendering

Returns:

String
HTML string

collection

(path, options) String deprecated

{{collection}} is a Ember.Handlebars helper for adding instances of Ember.CollectionView to a template. See Ember.CollectionView for additional information on how a CollectionView functions.

{{collection}}'s primary use is as a block helper with a contentBinding option pointing towards an Ember.Array-compatible object. An Ember.View instance will be created for each item in its content property. Each view will have its own content property set to the appropriate item in the collection.

The provided block will be applied as the template for each item's view.

Given an empty <body> the following template:

1
2
3
{{#collection contentBinding="App.items"}}
  Hi {{view.content.name}}
{{/collection}}

And the following application code

1
2
3
4
5
6
App = Ember.Application.create()
App.items = [
  Ember.Object.create({name: 'Dave'}),
  Ember.Object.create({name: 'Mary'}),
  Ember.Object.create({name: 'Sara'})
]

Will result in the HTML structure below

1
2
3
4
5
<div class="ember-view">
  <div class="ember-view">Hi Dave</div>
  <div class="ember-view">Hi Mary</div>
  <div class="ember-view">Hi Sara</div>
</div>

Blockless Use

If you provide an itemViewClass option that has its own template you can omit the block.

The following template:

1
{{collection contentBinding="App.items" itemViewClass="App.AnItemView"}}

And application code

1
2
3
4
5
6
7
8
9
10
App = Ember.Application.create();
App.items = [
  Ember.Object.create({name: 'Dave'}),
  Ember.Object.create({name: 'Mary'}),
  Ember.Object.create({name: 'Sara'})
];

App.AnItemView = Ember.View.extend({
  template: Ember.Handlebars.compile("Greetings {{view.content.name}}")
});

Will result in the HTML structure below

1
2
3
4
5
<div class="ember-view">
  <div class="ember-view">Greetings Dave</div>
  <div class="ember-view">Greetings Mary</div>
  <div class="ember-view">Greetings Sara</div>
</div>

Specifying a CollectionView subclass

By default the {{collection}} helper will create an instance of Ember.CollectionView. You can supply a Ember.CollectionView subclass to the helper by passing it as the first argument:

1
2
3
{{#collection App.MyCustomCollectionClass contentBinding="App.items"}}
  Hi {{view.content.name}}
{{/collection}}

Forwarded item.*-named Options

As with the {{view}}, helper options passed to the {{collection}} will be set on the resulting Ember.CollectionView as properties. Additionally, options prefixed with item will be applied to the views rendered for each item (note the camelcasing):

1
2
3
4
5
{{#collection contentBinding="App.items"
              itemTagName="p"
              itemClassNames="greeting"}}
  Howdy {{view.content.name}}
{{/collection}}

Will result in the following HTML structure:

1
2
3
4
5
<div class="ember-view">
  <p class="ember-view greeting">Howdy Dave</p>
  <p class="ember-view greeting">Howdy Mary</p>
  <p class="ember-view greeting">Howdy Sara</p>
</div>

Parameters:

path String
options Hash

Returns:

String
HTML string

control

(path, modelPath, options) String

The control helper is currently under development and is considered experimental. To enable it, set ENV.EXPERIMENTAL_CONTROL_HELPER = true before requiring Ember.

Parameters:

path String
modelPath String
options Hash

Returns:

String
HTML string

debugger

(property)

Execute the debugger statement in the current context.

1
{{debugger}}

Parameters:

property String

each

(name, path, options)

The {{#each}} helper loops over elements in a collection, rendering its block once for each item. It is an extension of the base Handlebars {{#each}} helper:

1
Developers = [{name: 'Yehuda'},{name: 'Tom'}, {name: 'Paul'}];
1
2
3
{{#each Developers}}
  {{name}}
{{/each}}

{{each}} supports an alternative syntax with element naming:

1
2
3
{{#each person in Developers}}
  {{person.name}}
{{/each}}

When looping over objects that do not have properties, {{this}} can be used to render the object:

1
DeveloperNames = ['Yehuda', 'Tom', 'Paul']
1
2
3
{{#each DeveloperNames}}
  {{this}}
{{/each}}

{{else}} condition

{{#each}} can have a matching {{else}}. The contents of this block will render if the collection is empty.

1
2
3
4
5
{{#each person in Developers}}
  {{person.name}}
{{else}}
  <p>Sorry, nobody is available for this task.</p>
{{/each}}

Specifying a View class for items

If you provide an itemViewClass option that references a view class with its own template you can omit the block.

The following template:

1
2
3
{{#view App.MyView }}
  {{each view.items itemViewClass="App.AnItemView"}}
{{/view}}

And application code

1
2
3
4
5
6
7
8
9
10
11
12
13
App = Ember.Application.create({
  MyView: Ember.View.extend({
    items: [
      Ember.Object.create({name: 'Dave'}),
      Ember.Object.create({name: 'Mary'}),
      Ember.Object.create({name: 'Sara'})
    ]
  })
});

App.AnItemView = Ember.View.extend({
  template: Ember.Handlebars.compile("Greetings {{name}}")
});

Will result in the HTML structure below

1
2
3
4
5
<div class="ember-view">
  <div class="ember-view">Greetings Dave</div>
  <div class="ember-view">Greetings Mary</div>
  <div class="ember-view">Greetings Sara</div>
</div>

Representing each item with a Controller.

By default the controller lookup within an {{#each}} block will be the controller of the template where the {{#each}} was used. If each item needs to be presented by a custom controller you can provide a itemController option which references a controller by lookup name. Each item in the loop will be wrapped in an instance of this controller and the item itself will be set to the content property of that controller.

This is useful in cases where properties of model objects need transformation or synthesis for display:

1
2
3
4
5
App.DeveloperController = Ember.ObjectController.extend({
  isAvailableForHire: function(){
    return !this.get('content.isEmployed') && this.get('content.isSeekingWork');
  }.property('isEmployed', 'isSeekingWork')
})
1
2
3
{{#each person in developers itemController="developer"}}
  {{person.name}} {{#if person.isAvailableForHire}}Hire me!{{/if}}
{{/each}}

Parameters:

name String
name for item (used with `in`)
path String
path
options Object
Handlebars key/value pairs of options

helperMissing

(path, options) private

Parameters:

path String
options Hash

if

(context, options) String

See boundIf

Parameters:

context Function
options Hash

Returns:

String
HTML string

linkTo

(routeName, context) String

Parameters:

routeName String
context Object

Returns:

String
HTML string

log

(property)

log allows you to output the value of a value in the current rendering context.

1
{{log myVariable}}

Parameters:

property String

outlet

(property)

The outlet helper is a placeholder that the router will fill in with the appropriate template based on the current state of the application.

1
{{outlet}}

By default, a template based on Ember's naming conventions will be rendered into the outlet (e.g. App.PostsRoute will render the posts template).

You can render a different template by using the render() method in the route's renderTemplate hook. The following will render the favoritePost template into the outlet.

1
2
3
4
5
App.PostsRoute = Ember.Route.extend({
  renderTemplate: function() {
    this.render('favoritePost');
  }
});

You can create custom named outlets for more control.

1
2
{{outlet favoritePost}}
{{outlet posts}}

Then you can define what template is rendered into each outlet in your route.

1
2
3
4
5
6
App.PostsRoute = Ember.Route.extend({
  renderTemplate: function() {
    this.render('favoritePost', { outlet: 'favoritePost' });
    this.render('posts', { outlet: 'posts' });
  }
});

Parameters:

property String
the property on the controller that holds the view for this outlet

partial

(partialName)

partial renders a template directly using the current context. If needed the context can be set using the {{#with foo}} helper.

1
2
3
4
5
<script type="text/x-handlebars" data-template-name="header_bar">
  {{#with currentUser}}
    {{partial user_info}}
  {{/with}}
</script>

The data-template-name attribute of a partial template is prefixed with an underscore.

1
2
3
<script type="text/x-handlebars" data-template-name="_user_info">
  <span>Hello {{username}}!</span>
</script>

Parameters:

partialName String
the name of the template to render minus the leading underscore

render

(name, contextString, options)

Renders the named template in the current context using the singleton instance of the same-named controller.

If a view class with the same name exists, uses the view class.

If a model is specified, it becomes the model for that controller.

The default target for {{action}}s in the rendered template is the named controller.

Parameters:

name String
contextString Object?
options Hash

template

(templateName)

template allows you to render a template from inside another template. This allows you to re-use the same template in multiple places. For example:

1
2
3
4
5
6
<script type="text/x-handlebars" data-template-name="logged_in_user">
  {{#with loggedInUser}}
    Last Login: {{lastLogin}}
    User Info: {{template "user_info"}}
  {{/with}}
</script>
1
2
3
4
<script type="text/x-handlebars" data-template-name="user_info">
  Name: <em>{{name}}</em>
  Karma: <em>{{karma}}</em>
</script>
1
2
3
4
5
{{#if isUser}}
  {{template "user_info"}}
{{else}}
  {{template "unlogged_user_info"}}
{{/if}}

This helper looks for templates in the global Ember.TEMPLATES hash. If you add <script> tags to your page with the data-template-name attribute set, they will be compiled and placed in this hash automatically.

You can also manually register templates by adding them to the hash:

1
Ember.TEMPLATES["my_cool_template"] = Ember.Handlebars.compile('<b>{{user}}</b>');

Parameters:

templateName String
the template to render

unbound

(property) String

unbound allows you to output a property without binding. Important: The output will not be updated if the property changes. Use with caution.

1
<div>{{unbound somePropertyThatDoesntChange}}</div>

unbound can also be used in conjunction with a bound helper to render it in its unbound form:

1
<div>{{unbound helperName somePropertyThatDoesntChange}}</div>

Parameters:

property String

Returns:

String
HTML string

unless

(context, options) String

Parameters:

context Function
options Hash

Returns:

String
HTML string

view

(path, options) String

{{view}} inserts a new instance of Ember.View into a template passing its options to the Ember.View's create method and using the supplied block as the view's own template.

An empty <body> and the following template:

1
2
3
4
A span:
{{#view tagName="span"}}
  hello.
{{/view}}

Will result in HTML structure:

1
2
3
4
5
6
7
8
9
10
11
12
<body>
  <!-- Note: the handlebars template script
       also results in a rendered Ember.View
       which is the outer <div> here -->

  <div class="ember-view">
    A span:
    <span id="ember1" class="ember-view">
      Hello.
    </span>
  </div>
</body>

parentView setting

The parentView property of the new Ember.View instance created through {{view}} will be set to the Ember.View instance of the template where {{view}} was called.

1
2
3
4
5
aView = Ember.View.create({
  template: Ember.Handlebars.compile("{{#view}} my parent: {{parentView.elementId}} {{/view}}")
});

aView.appendTo('body');

Will result in HTML structure:

1
2
3
4
5
<div id="ember1" class="ember-view">
  <div id="ember2" class="ember-view">
    my parent: ember1
  </div>
</div>

Setting CSS id and class attributes

The HTML id attribute can be set on the {{view}}'s resulting element with the id option. This option will not be passed to Ember.View.create.

1
2
3
{{#view tagName="span" id="a-custom-id"}}
  hello.
{{/view}}

Results in the following HTML structure:

1
2
3
4
5
<div class="ember-view">
  <span id="a-custom-id" class="ember-view">
    hello.
  </span>
</div>

The HTML class attribute can be set on the {{view}}'s resulting element with the class or classNameBindings options. The class option will directly set the CSS class attribute and will not be passed to Ember.View.create. classNameBindings will be passed to create and use Ember.View's class name binding functionality:

1
2
3
{{#view tagName="span" class="a-custom-class"}}
  hello.
{{/view}}

Results in the following HTML structure:

1
2
3
4
5
<div class="ember-view">
  <span id="ember2" class="ember-view a-custom-class">
    hello.
  </span>
</div>

Supplying a different view class

{{view}} can take an optional first argument before its supplied options to specify a path to a custom view class.

1
2
3
{{#view "MyApp.CustomView"}}
  hello.
{{/view}}

The first argument can also be a relative path accessible from the current context.

1
2
3
4
5
6
7
8
9
MyApp = Ember.Application.create({});
MyApp.OuterView = Ember.View.extend({
  innerViewClass: Ember.View.extend({
    classNames: ['a-custom-view-class-as-property']
  }),
  template: Ember.Handlebars.compile('{{#view "view.innerViewClass"}} hi {{/view}}')
});

MyApp.OuterView.create().appendTo('body');

Will result in the following HTML:

1
2
3
4
5
<div id="ember1" class="ember-view">
  <div id="ember2" class="ember-view a-custom-view-class-as-property">
    hi
  </div>
</div>

Blockless use

If you supply a custom Ember.View subclass that specifies its own template or provide a templateName option to {{view}} it can be used without supplying a block. Attempts to use both a templateName option and supply a block will throw an error.

1
{{view "MyApp.ViewWithATemplateDefined"}}

viewName property

You can supply a viewName option to {{view}}. The Ember.View instance will be referenced as a property of its parent view by this name.

1
2
3
4
5
6
aView = Ember.View.create({
  template: Ember.Handlebars.compile('{{#view viewName="aChildByName"}} hi {{/view}}')
});

aView.appendTo('body');
aView.get('aChildByName') // the instance of Ember.View created by {{view}} helper

Parameters:

path String
options Hash

Returns:

String
HTML string

with

(context, options) String

Parameters:

context Function
options Hash

Returns:

String
HTML string

yield

(options) String

When used in a Handlebars template that is assigned to an Ember.View instance's layout property Ember will render the layout template first, inserting the view's own rendered output at the {{yield}} location.

An empty <body> and the following application code:

1
2
3
4
5
6
7
8
AView = Ember.View.extend({
  classNames: ['a-view-with-layout'],
  layout: Ember.Handlebars.compile('<div class="wrapper">{{yield}}</div>'),
  template: Ember.Handlebars.compile('<span>I am wrapped</span>')
});

aView = AView.create();
aView.appendTo('body');

Will result in the following HTML output:

1
2
3
4
5
6
7
<body>
  <div class='ember-view a-view-with-layout'>
    <div class="wrapper">
      <span>I am wrapped</span>
    </div>
  </div>
</body>

The yield helper cannot be used outside of a template assigned to an Ember.View's layout property and will throw an error if attempted.

1
2
3
4
5
6
7
8
9
10
BView = Ember.View.extend({
  classNames: ['a-view-with-layout'],
  template: Ember.Handlebars.compile('{{yield}}')
});

bView = BView.create();
bView.appendTo('body');

// throws
// Uncaught Error: assertion failed: You called yield in a template that was not a layout

Parameters:

options Hash

Returns:

String
HTML string