Ember.Handlebars.helpers Class packages/ember-handlebars-compiler/lib/main.js:119
Defined in: packages/ember-handlebars-compiler/lib/main.js:119
Module: ember-handlebars-compiler
Methods
_finishDisconnections
private
_hasEquivalentView
(outletName, view)
Boolean
private
Parameters:
- outletName String
- The name of the outlet we are checking
- view Object
- An Ember.View
Returns:
- Boolean
_triageMustache
(property, options)
String
private
Parameters:
- property String
- Property/helperID to triage
- options Object
- hash of template/rendering options
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 templates's controller
or supplied target
option (see 'Specifying a Target').
If the 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 application Handlebars template on the page
And application code
1 2 3 4 5 6 7 |
App.ApplicationController = Ember.Controller.extend({ actions: { anActionName: function() { } } }); |
Will result 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
action of the
App.ApplicationController
. In this case, no additional parameters will be passed.
If you provide additional parameters to the helper:
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:
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:
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.
This way the {{action}}
will fire when clicking with the alt key pressed down.
Alternatively, supply "any" to the allowedKeys
option to accept any combination of modifier keys.
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
to an object, accessible in the current context:
1 2 3 4 5 6 |
App.ApplicationView = Ember.View.extend({ actions: { anActionName: function(){} } }); |
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.
Clicking "click me" will trigger the edit
method on the current controller
with the value of person
as a parameter.
Parameters:
- actionName String
- context Object
- options Hash
bind-attr
(options)
String
bind-attr
allows you to create a binding between DOM element attributes and
Ember objects. For example:
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"> |
bind-attr
cannot redeclare existing DOM element attributes. The use of src
in the following bind-attr
example will be ignored and the hard coded value
of src="/failwhale.gif"
will take precedence:
bind-attr
and the class
attribute
bind-attr
supports a special syntax for handling a number of cases unique
to the class
DOM element attribute. The class
attribute combines
multiple discrete 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 bind-attr
. 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() }) |
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 }) |
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:
A hard-coded value can be used by prepending :
to the desired
class name: :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:
Parameters:
- options Hash
Returns:
- String
- HTML string
bindAttr
(context, options)
String
deprecated
See bind-attr
Parameters:
- context Function
- options Hash
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:
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:
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:
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):
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
connectOutlet
(outletName, view)
Manually fill any of a view's {{outlet}}
areas with the
supplied view.
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var MyView = Ember.View.extend({ template: Ember.Handlebars.compile('Child view: {{outlet "main"}} ') }); var myView = MyView.create(); myView.appendTo('body'); // The html for myView now looks like: // <div id="ember228" class="ember-view">Child view: </div> myView.connectOutlet('main', Ember.View.extend({ template: Ember.Handlebars.compile('<h1>Foo</h1> ') })); // The html for myView now looks like: // <div id="ember228" class="ember-view">Child view: // <div id="ember234" class="ember-view"><h1>Foo</h1> </div> // </div> |
Parameters:
- outletName String
- A unique name for the outlet
- view Object
- An Ember.View
control
(path, modelPath, options)
String
{{control}}
works like render, except it uses a new controller instance for every call, instead of reusing the singleton controller.
The control helper is currently under development and is considered experimental.
To enable it, set ENV.EXPERIMENTAL_CONTROL_HELPER = true
before requiring Ember.
For example if you had this author
template.
You could render it inside the post
template using the control
helper.
Returns:
- String
- HTML string
debugger
(property)
Execute the debugger
statement in the current context.
Parameters:
- property String
disconnectOutlet
(outletName)
Removes an outlet from the view.
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
var MyView = Ember.View.extend({ template: Ember.Handlebars.compile('Child view: {{outlet "main"}} ') }); var myView = MyView.create(); myView.appendTo('body'); // myView's html: // <div id="ember228" class="ember-view">Child view: </div> myView.connectOutlet('main', Ember.View.extend({ template: Ember.Handlebars.compile('<h1>Foo</h1> ') })); // myView's html: // <div id="ember228" class="ember-view">Child view: // <div id="ember234" class="ember-view"><h1>Foo</h1> </div> // </div> myView.disconnectOutlet('main'); // myView's html: // <div id="ember228" class="ember-view">Child view: </div> |
Parameters:
- outletName String
- The name of the outlet to be removed
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'}]; |
{{each}}
supports an alternative syntax with element naming:
When looping over objects that do not have properties, {{this}}
can be used
to render the object:
1 |
DeveloperNames = ['Yehuda', 'Tom', 'Paul'] |
{{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:
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> |
If an itemViewClass
is defined on the helper, and therefore the helper is not
being used as a block, an emptyViewClass
can also be provided optionally.
The emptyViewClass
will match the behavior of the {{else}}
condition
described above. That is, the emptyViewClass
will render if the collection
is empty.
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') }) |
Each itemController will receive a reference to the current controller as
a parentController
property.
(Experimental) Grouped Each
When used in conjunction with the experimental group helper, you can inform Handlebars to re-render an entire group of items instead of re-rendering them one at a time (in the event that they are changed en masse or an item is added/removed).
This can be faster than the normal way that Handlebars re-renders items in some cases.
If for some reason you have a group with more than one #each
, you can make
one of the collections be updated in normal (non-grouped) fashion by setting
the option groupedRows=true
(counter-intuitive, I know).
For example,
Any change to dealershipName
or the dealers
collection will cause the
entire group to be re-rendered. However, changes to the cars
collection
will be re-rendered individually (as normal).
Note that group
behavior is also disabled by specifying an itemViewClass
.
if
(context, options)
String
See boundIf
Parameters:
- context Function
- options Hash
Returns:
- String
- HTML string
init
Sets the private _outlets
object on the view.
input
(options)
The {{input}}
helper inserts an HTML <input>
tag into the template,
with a type
value of either text
or checkbox
. If no type
is provided,
text
will be the default value applied. The attributes of {{input}}
match those of the native HTML tag as closely as possible for these two types.
Use as text field
An {{input}}
with no type
or a type
of text
will render an HTML text input.
The following HTML attributes can be set via the helper:
value
size
name
pattern
placeholder
disabled
maxlength
tabindex
When set to a quoted string, these values will be directly applied to the HTML element. When left unquoted, these values will be bound to a property on the template's current rendering context (most typically a controller instance).
Unbound:
1 |
<input type="text" value="http://www.facebook.com"/> |
Bound:
1 2 3 4 |
App.ApplicationController = Ember.Controller.extend({ firstName: "Stanley", entryNotAllowed: true }); |
1 |
<input type="text" value="Stanley" disabled="disabled" size="50"/> |
Extension
Internally, {{input type="text"}}
creates an instance of Ember.TextField
, passing
arguments from the helper to Ember.TextField
's create
method. You can extend the
capablilties of text inputs in your applications by reopening this class. For example,
if you are deploying to browsers where the required
attribute is used, you
can add this to the TextField
's attributeBindings
property:
javascript
Ember.TextField.reopen({
attributeBindings: ['required']
});
Keep in mind when writing Ember.TextField
subclasses that Ember.TextField
itself extends Ember.Component
, meaning that it does NOT inherit
the controller
of the parent view.
See more about Ember components
Use as checkbox
An {{input}}
with a type
of checkbox
will render an HTML checkbox input.
The following HTML attributes can be set via the helper:
checked
disabled
tabindex
indeterminate
name
When set to a quoted string, these values will be directly applied to the HTML element. When left unquoted, these values will be bound to a property on the template's current rendering context (most typically a controller instance).
Unbound:
1 |
<input type="checkbox" name="isAdmin" /> |
Bound:
1 2 3 |
App.ApplicationController = Ember.Controller.extend({ isAdmin: true }); |
1 |
<input type="checkbox" checked="checked" /> |
Extension
Internally, {{input type="checkbox"}}
creates an instance of Ember.Checkbox
, passing
arguments from the helper to Ember.Checkbox
's create
method. You can extend the
capablilties of checkbox inputs in your applications by reopening this class. For example,
if you wanted to add a css class to all checkboxes in your application:
javascript
Ember.Checkbox.reopen({
classNames: ['my-app-checkbox']
});
Parameters:
- options Hash
link-to
(routeName, context, options)
String
The {{link-to}}
helper renders a link to the supplied
routeName
passing an optionally supplied model to the
route as its model
context of the route. The block
for {{link-to}}
becomes the innerHTML of the rendered
element:
1 2 3 |
<a href="/hamster-photos"> Great Hamster Photos </a> |
Supplying a tagName
By default {{link-to}}
renders an <a>
element. This can
be overridden for a single use of {{link-to}}
by supplying
a tagName
option:
1 2 3 |
<li> Great Hamster Photos </li> |
To override this option for your entire application, see "Overriding Application-wide Defaults".
Disabling the link-to
helper
By default {{link-to}}
is enabled.
any passed value to disabled
helper property will disable the link-to
helper.
static use: the disabled
option:
dynamic use: the disabledWhen
option:
any passed value to disabled
will disable it except undefined
.
to ensure that only true
disable the link-to
helper you can
override the global behaviour of Ember.LinkView
.
1 2 3 4 5 6 7 8 |
Ember.LinkView.reopen({ disabled: Ember.computed(function(key, value) { if (value !== undefined) { this.set('_isDisabled', value === true); } return value === true ? get(this, 'disabledClass') : false; }) }); |
see "Overriding Application-wide Defaults" for more.
Handling href
{{link-to}}
will use your application's Router to
fill the element's href
property with a url that
matches the path to the supplied routeName
for your
routers's configured Location
scheme, which defaults
to Ember.HashLocation.
Handling current route
{{link-to}}
will apply a CSS class name of 'active'
when the application's current route matches
the supplied routeName. For example, if the application's
current route is 'photoGallery.recent' the following
use of {{link-to}}
:
will result in
1 2 3 |
<a href="/hamster-photos/this-week" class="active"> Great Hamster Photos </a> |
The CSS class name used for active classes can be customized
for a single use of {{link-to}}
by passing an activeClass
option:
1 2 3 |
<a href="/hamster-photos/this-week" class="current-url"> Great Hamster Photos </a> |
To override this option for your entire application, see "Overriding Application-wide Defaults".
Supplying a model
An optional model argument can be used for routes whose paths contain dynamic segments. This argument will become the model context of the linked route:
1 2 3 |
App.Router.map(function() { this.resource("photoGallery", {path: "hamster-photos/:photo_id"}); }); |
1 2 3 |
<a href="/hamster-photos/42"> Tomster </a> |
Supplying multiple models
For deep-linking to route paths that contain multiple dynamic segments, multiple model arguments can be used. As the router transitions through the route path, each supplied model argument will become the context for the route with the dynamic segments:
1 2 3 4 5 |
App.Router.map(function() { this.resource("photoGallery", {path: "hamster-photos/:photo_id"}, function() { this.route("comment", {path: "comments/:comment_id"}); }); }); |
This argument will become the model context of the linked route:
1 2 3 |
<a href="/hamster-photos/42/comment/718"> A+++ would snuggle again. </a> |
Supplying an explicit dynamic segment value
If you don't have a model object available to pass to {{link-to}}
,
an optional string or integer argument can be passed for routes whose
paths contain dynamic segments. This argument will become the value
of the dynamic segment:
1 2 3 |
App.Router.map(function() { this.resource("photoGallery", {path: "hamster-photos/:photo_id"}); }); |
1 2 3 |
<a href="/hamster-photos/42"> Tomster </a> |
When transitioning into the linked route, the model
hook will
be triggered with parameters including this passed identifier.
Overriding attributes
You can override any given property of the Ember.LinkView
that is generated by the {{link-to}}
helper by passing
key/value pairs, like so:
See Ember.LinkView for a
complete list of overrideable properties. Be sure to also
check out inherited properties of LinkView
.
Overriding Application-wide Defaults
{{link-to}}
creates an instance of Ember.LinkView
for rendering. To override options for your entire
application, reopen Ember.LinkView and supply the
desired values:
1 2 3 4 |
Ember.LinkView.reopen({ activeClass: "is-active", tagName: 'li' }) |
It is also possible to override the default event in this manner:
1 2 3 |
Ember.LinkView.reopen({ eventName: 'customEventName' }); |
Parameters:
- routeName String
- context Object
- options Object
- Handlebars key/value pairs of options, you can override any property of Ember.LinkView
Returns:
- String
- HTML string
linkTo
(routeName, context)
String
deprecated
See link-to
Parameters:
- routeName String
- context Object
Returns:
- String
- HTML string
loc
(str)
loc
looks up the string in the localized strings hash.
This is a convenient way to localize text. For example:
1 2 3 |
<script type="text/x-handlebars" data-template-name="home"> {{loc "welcome"}} </script> |
Take note that "welcome"
is a string and not an object
reference.
Parameters:
- str String
- The string to format
log
(property)
log
allows you to output the value of a variable in the current rendering
context.
Parameters:
- property String
outlet
(property)
String
The outlet
helper is a placeholder that the router will fill in with
the appropriate template based on the current state of the application.
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.
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' }); } }); |
You can specify the view class that the outlet uses to contain and manage the templates rendered into it.
1 2 3 4 |
App.SectionContainer = Ember.ContainerView.extend({ tagName: 'section', classNames: ['special'] }); |
Parameters:
- property String
- the property on the controller that holds the view for this outlet
Returns:
- String
- HTML string
partial
(partialName)
The partial
helper renders another template without
changing the template context:
The above example template will render a template named
"nav", which has the same context as the parent template
it's rendered into, so if the "nav" template also referenced
{{foo}}
, it would print the same thing as the {{foo}}
in the above example.
If a "_nav" template isn't found, the partial
helper will
fall back to a template named "nav".
Bound template names
The parameter supplied to partial
can also be a path
to a property containing a template name, e.g.:
The above example will look up the value of someTemplateName
on the template context (e.g. a controller) and use that
value as the name of the template to render. If the resolved
value is falsy, nothing will be rendered. If someTemplateName
changes, the partial will be re-rendered using the new template
name.
Setting the partial's context with with
The partial
helper can be used in conjunction with the with
helper to set a context that will be used by the partial:
Parameters:
- partialName String
- the name of the template to render minus the leading underscore
render
(name, contextString, options)
String
Calling {{render}}
from within a template will insert another
template that matches the provided name. The inserted template will
access its properties on its own controller (rather than the controller
of the parent template).
If a view class with the same name exists, the view class also will be used.
Note: A given controller may only be used once in your app in this manner. A singleton instance of the controller will be created for you.
Example:
1 2 3 |
App.NavigationController = Ember.Controller.extend({ who: "world" }); |
1 2 3 4 |
<h1>My great app</h1> <div class='ember-view'> Hello, world. </div> |
Optionally you may provide a second argument: a property path
that will be bound to the model
property of the controller.
If a model
property path is specified, then a new instance of the
controller will be created and {{render}}
can be used multiple times
with the same name.
For example if you had this author
template.
You could render it inside the post
template using the render
helper.
Parameters:
- name String
- contextString Object?
- options Hash
Returns:
- String
- HTML string
template
(templateName)
deprecated
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> |
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
textarea
(options)
{{textarea}}
inserts a new instance of <textarea>
tag into the template.
The attributes of {{textarea}}
match those of the native HTML tags as
closely as possible.
The following HTML attributes can be set:
value
name
rows
cols
placeholder
disabled
maxlength
tabindex
When set to a quoted string, these value will be directly applied to the HTML element. When left unquoted, these values will be bound to a property on the template's current rendering context (most typically a controller instance).
Unbound:
Would result in the following HTML:
1 2 3 |
<textarea class="ember-text-area"> Lots of static text that ISN'T bound </textarea> |
Bound:
In the following example, the writtenWords
property on App.ApplicationController
will be updated live as the user types 'Lots of text that IS bound' into
the text area of their browser's window.
1 2 3 |
App.ApplicationController = Ember.Controller.extend({ writtenWords: "Lots of text that IS bound" }); |
Would result in the following HTML:
1 2 3 |
<textarea class="ember-text-area"> Lots of text that IS bound </textarea> |
If you wanted a one way binding between the text area and a div tag
somewhere else on your screen, you could use Ember.computed.oneWay
:
1 2 3 4 |
App.ApplicationController = Ember.Controller.extend({ writtenWords: "Lots of text that IS bound", outputWrittenWords: Ember.computed.oneWay("writtenWords") }); |
Would result in the following HTML:
1 2 3 4 5 6 7 8 9 |
<textarea class="ember-text-area"> Lots of text that IS bound </textarea> <-- the following div will be updated in real time as you type --> <div> Lots of text that IS bound </div> |
Finally, this example really shows the power and ease of Ember when two
properties are bound to eachother via Ember.computed.alias
. Type into
either text area box and they'll both stay in sync. Note that
Ember.computed.alias
costs more in terms of performance, so only use it when
your really binding in both directions:
1 2 3 4 |
App.ApplicationController = Ember.Controller.extend({ writtenWords: "Lots of text that IS bound", twoWayWrittenWords: Ember.computed.alias("writtenWords") }); |
1 2 3 4 5 6 7 8 9 |
<textarea id="ember1" class="ember-text-area"> Lots of text that IS bound </textarea> <-- both updated in real time --> <textarea id="ember2" class="ember-text-area"> Lots of text that IS bound </textarea> |
Extension
Internally, {{textarea}}
creates an instance of Ember.TextArea
, passing
arguments from the helper to Ember.TextArea
's create
method. You can
extend the capabilities of text areas in your application by reopening this
class. For example, if you are deploying to browsers where the required
attribute is used, you can globally add support for the required
attribute
on all {{textarea}}'s' in your app by reopening Ember.TextArea
or
Ember.TextSupport
and adding it to the attributeBindings
concatenated
property:
1 2 3 |
Ember.TextArea.reopen({ attributeBindings: ['required'] }); |
Keep in mind when writing Ember.TextArea
subclasses that Ember.TextArea
itself extends Ember.Component
, meaning that it does NOT inherit
the controller
of the parent view.
See more about Ember components
Parameters:
- options Hash
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.
unbound
can also be used in conjunction with a bound helper to
render it in its unbound form:
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:
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
.
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:
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.
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.
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
{{yield}}
denotes an area of a template that will be rendered inside
of another template. It has two main uses:
Use with layout
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 11 |
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 |
Use with Ember.Component
When designing components {{yield}}
is used to denote where, inside the component's
template, an optional block passed to the component should render:
Result:
1 2 3 |
<label> First name: <input type="text" /> <label> |
Parameters:
- options Hash
Returns:
- String
- HTML string