Ember.Templates.helpers Class
Module: ember-routing-views
Methods
action
public
The {{action}}
helper provides a way to pass triggers for behavior (usually
just a function) between components, and into components from controllers.
Passing functions with the action helper
There are three contexts an action helper can be used in. The first two contexts to discuss are attribute context, and Handlebars value context.
In these contexts,
the helper is called a "closure action" helper. Its behavior is simple:
If passed a function name, read that function off the actions
property
of the current context. Once that function is read (or if a function was
passed), create a closure over that function and any arguments.
The resulting value of an action helper used this way is simply a function. For example, in the attribute context:
The resulting template render logic would be:
1 2 3 4 5 6 7 |
var div = document.createElement('div'); var actionFunction = (function(context){ return function() { return context.actions.save.apply(context, arguments); }; })(context); div.onclick = actionFunction; |
Thus when the div is clicked, the action on that context is called.
Because the actionFunction
is just a function, closure actions can be
passed between components and still execute in the correct context.
Here is an example action handler on a component:
1 2 3 4 5 6 7 |
export default Ember.Component.extend({ actions: { save() { this.get('model').save(); } } }); |
Actions are always looked up on the actions
property of the current context.
This avoids collisions in the naming of common actions, such as destroy
.
Two options can be passed to the action
helper when it is used in this way.
target=someProperty
will look tosomeProperty
instead of the current context for theactions
hash. This can be useful when targetting a service for actions.value="target.value"
will read the pathtarget.value
off the first argument to the action when it is called and rewrite the first argument to be that value. This is useful when attaching actions to event listeners.
Invoking an action
Closure actions curry both their scope and any arguments. When invoked, any additional arguments are added to the already curried list.
Actions should be invoked using the sendAction
method. The first argument to sendAction
is the action to be called, and
additional arguments are passed to the action function. This has interesting
properties combined with currying of arguments. For example:
1 2 3 4 5 6 7 8 |
export default Ember.Component.extend({ actions: { // Usage {{input on-input=(action (action 'setName' model) value="target.value")}} setName(model, name) { model.set('name', name); } } }); |
The first argument (model
) was curried over, and the run-time argument (event
)
becomes a second argument. Action calls can be nested this way because each simply
returns a function. Any function can be passed to the {{action}}
helper, including
other actions.
Actions invoked with sendAction
have the same currying behavior as demonstrated
with on-input
above. For example:
1 2 3 4 5 6 7 |
export default Ember.Component.extend({ actions: { setName(model, name) { model.set('name', name); } } }); |
1 2 3 4 5 6 7 |
// app/components/my-component.js export default Ember.Component.extend({ click() { // Note that model is not passed, it was curried in the template this.sendAction('submit', 'bob'); } }); |
Attaching actions to DOM elements
The third context of the {{action}}
helper can be called "element space".
For example:
Used this way, the {{action}}
helper provides a useful shortcut for
registering an HTML element in a template for a single DOM event and
forwarding that interaction to the template's context (controller or component).
If the context of a template is a controller, actions used this way will bubble to routes when the controller does not implement the specified action. Once an action hits a route, it will bubble through the route hierarchy.
Event Propagation
{{action}}
helpers called in element space can control event bubbling. Note
that the closure style actions cannot.
Events triggered through the action helper will automatically have
.preventDefault()
called on them. You do not need to do so in your event
handlers. If you need to allow event propagation (to handle file inputs for
example) you can supply the preventDefault=false
option to the {{action}}
helper:
To disable bubbling, pass bubbles=false
to the helper:
To disable bubbling with closure style actions you must create your own
wrapper helper that makes use of event.stopPropagation()
:
1 2 3 4 5 6 7 8 9 10 11 12 |
// app/helpers/disable-bubbling.js import Ember from 'ember'; export function disableBubbling([action]) { return function(event) { event.stopPropagation(); return action(event); }; } export default Ember.Helper.helper(disableBubbling); |
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 "Responding to Browser Events" in the documentation for Ember.View for more information.
Specifying DOM event type
{{action}}
helpers called in element space can specify an 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 "Event Names" for a list of acceptable DOM event names.
Specifying whitelisted modifier keys
{{action}}
helpers called in element space can specify modifier keys.
By default the {{action}}
helper will ignore click events 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
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 |
// app/controllers/application.js export default Ember.Controller.extend({ someService: Ember.inject.service() }); |
collection
deprecated
public
Use {{each}}
helper instead.
{{collection}}
is a template 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.ApplicationRoute = Ember.Route.extend({ model() { return [{name: 'Yehuda'},{name: 'Tom'},{name: 'Peter'}]; } }); |
The following HTML will result:
1 2 3 4 5 |
<div class="ember-view"> <div class="ember-view">Hi Yehuda</div> <div class="ember-view">Hi Tom</div> <div class="ember-view">Hi Peter</div> </div> |
Non-block version of collection
If you provide an itemViewClass
option that has its own template
,
then you may omit the block.
The following template:
And application code
1 2 3 4 5 6 7 8 9 10 |
App = Ember.Application.create(); App.ApplicationRoute = Ember.Route.extend({ model() { return [{name: 'Yehuda'},{name: 'Tom'},{name: 'Peter'}]; } }); 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 Yehuda</div> <div class="ember-view">Greetings Tom</div> <div class="ember-view">Greetings Peter</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:
This example would look for the class App.MyCustomCollection
.
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 Yehuda</p> <p class="ember-view greeting">Howdy Tom</p> <p class="ember-view greeting">Howdy Peter</p> </div> |
component
public
The {{component}}
helper lets you add instances of Ember.Component
to a
template. See Ember.Component for
additional information on how a Component
functions.
{{component}}
's primary use is for cases where you want to dynamically
change which type of component is rendered as the state of your application
changes. The provided block will be applied as the template for the component.
Given an empty <body>
the following template:
And the following application code:
1 2 3 4 5 6 7 8 9 10 11 |
export default Ember.Controller.extend({ infographicComponentName: computed('isMarketOpen', { get() { if (this.get('isMarketOpen')) { return 'live-updating-chart'; } else { return 'market-close-summary'; } } }) }); |
The live-updating-chart
component will be appended when isMarketOpen
is
true
, and the market-close-summary
component will be appended when
isMarketOpen
is false
. If the value changes while the app is running,
the component will be automatically swapped out accordingly.
Note: You should not use this helper when you are consistently rendering the same
component. In that case, use standard component syntax, for example:
Nested Usage
The component
helper can be used to package a component path with initial attrs.
The included attrs can then be merged during the final invocation.
For example, given a person-form
component with the following template:
The following snippet:
1 2 3 |
{{#person-form as |form|}} {{component form.nameInput placeholder="Username"}} {{/person-form}} |
would output an input whose value is already bound to model.name
and placeholder
is "Username".
concat
public
Concatenates the given arguments into a string.
Example:
debugger
public
Execute the debugger
statement in the current template's context.
When using the debugger helper you will have access to a get
function. This
function retrieves values available in the context of the template.
For example, if you're wondering why a value {{foo}}
isn't rendering as
expected within a template, you could place a {{debugger}}
statement and,
when the debugger;
breakpoint is hit, you can attempt to retrieve this value:
1 |
> get('foo') |
get
is also aware of keywords. So in this situation
You'll be able to get values from the current item:
1 |
> get('item.name') |
You can also access the context of the view to make sure it is the object that you expect:
1 |
> context |
each
public
The {{#each}}
helper loops over elements in a collection. It is an extension
of the base Handlebars {{#each}}
helper.
The default behavior of {{#each}}
is to yield its inner block once for every
item in an array passing the item as the first block parameter.
1 |
var developers = [{name: 'Yehuda'},{name: 'Tom'}, {name: 'Paul'}]; |
The same rules apply to arrays of primitives.
1 |
var developerNames = ['Yehuda', 'Tom', 'Paul'] |
During iteration, the index of each item in the array is provided as a second block parameter.
Specifying Keys
The key
option is used to tell Ember how to determine if the array being
iterated over with {{#each}}
has changed between renders. By helping Ember
detect that some elements in the array are the same, DOM elements can be
re-used, significantly improving rendering speed.
For example, here's the {{#each}}
helper with its key
set to id
:
When this {{#each}}
re-renders, Ember will match up the previously rendered
items (and reorder the generated DOM elements) based on each item's id
property.
By default the item's own reference is used.
{{else}} condition
{{#each}}
can have a matching {{else}}
. The contents of this block will render
if the collection is empty.
each-in
public
The {{each-in}}
helper loops over properties on an object. It is unbound,
in that new (or removed) properties added to the target object will not be
rendered.
For example, given a user
object that looks like:
1 2 3 4 |
{ "name": "Shelly Sails", "age": 42 } |
This template would display all properties on the user
object in a list:
Outputting their name and age.
get
public
Dynamically look up a property on an object. The second argument to {{get}}
should have a string value, although it can be bound.
For example, these two usages are equivilent:
If there were several facts about a person, the {{get}}
helper can dynamically
pick one:
For a more complex example, this template would allow the user to switch between showing the user's height and weight with a click:
The {{get}}
helper can also respect mutable values itself. For example:
Would allow the user to swap what fact is being displayed, and also edit that fact via a two-way mutable binding.
hash
(options)
Object
public
Use the {{hash}}
helper to create a hash to pass as an option to your
components. This is specially useful for contextual components where you can
just yield a hash:
Would result in an object such as:
1 |
{ name: 'Sarah', title: this.get('office') } |
Where the title
is bound to updates of the office
property.
Parameters:
- options Object
Returns:
- Object
- Hash
if
public
Use the if
block helper to conditionally render a block depending on a
property. If the property is "falsey", for example: false
, undefined
,
null
, ""
, 0
, NaN
or an empty array, the block will not be rendered.
You can also specify a template to show if the property is falsey by using
the else
helper.
You are also able to combine else
and if
helpers to create more complex
conditional logic.
You can use if
inline to conditionally render a single property or string.
This helper acts like a ternary operator. If the first property is truthy,
the second argument will be displayed, if not, the third argument will be
displayed
Finally, you can use the if
helper inside another helper as a subexpression.
input
(options)
public
The {{input}}
helper lets you create an HTML <input />
component.
It causes an Ember.TextField
component to be rendered. For more info,
see the Ember.TextField docs and
the templates guide.
renders as:
1 |
<input type="text" value="987" /> |
Text field
If no type
option is specified, a default of type 'text' is used.
Many of the standard HTML attributes may be passed to this helper.
`readonly` | `required` | `autofocus` |
`value` | `placeholder` | `disabled` |
`size` | `tabindex` | `maxlength` |
`name` | `min` | `max` |
`pattern` | `accept` | `autocomplete` |
`autosave` | `formaction` | `formenctype` |
`formmethod` | `formnovalidate` | `formtarget` |
`height` | `inputmode` | `multiple` |
`step` | `width` | `form` |
`selectionDirection` | `spellcheck` |
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).
A very common use of this helper is to bind the value
of an input to an Object's attribute:
In this example, the inital value in the <input />
will be set to the value of searchWord
.
If the user changes the text, the value of searchWord
will also be updated.
Actions
The helper can send multiple actions based on user events. The action property defines the action which is sent when the user presses the return key.
The helper allows some user events to send actions.
enter
insert-newline
escape-press
focus-in
focus-out
key-press
key-up
For example, if you desire an action to be sent when the input is blurred, you only need to setup the action name to the event name property.
See more about Text Support Actions
Extending Ember.TextField
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
capabilities of text inputs in your applications by reopening this class. For example,
if you are building a Bootstrap project where data-*
attributes are used, you
can add one to the TextField
's attributeBindings
property:
1 2 3 |
Ember.TextField.reopen({ attributeBindings: ['data-error'] }); |
Keep in mind when writing Ember.TextField
subclasses that Ember.TextField
itself extends Ember.Component
. Expect isolated component semantics, not
legacy 1.x view semantics (like controller
being present).
See more about Ember components
Checkbox
Checkboxes are special forms of the {{input}}
helper. To create a <checkbox />
:
This will bind checked state of this checkbox to the value of isEmberized
-- if either one changes,
it will be reflected in the other.
The following HTML attributes can be set via the helper:
checked
disabled
tabindex
indeterminate
name
autofocus
form
Extending Ember.Checkbox
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:
1 2 3 |
Ember.Checkbox.reopen({ classNames: ['my-app-checkbox'] }); |
Parameters:
- options Hash
link-to
(routeName, context, options)
String
public
The {{link-to}}
component 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:
You can also use an inline form of {{link-to}}
component by
passing the link text as the first argument
to the component:
Both will result in:
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
component
By default {{link-to}}
is enabled.
any passed value to the disabled
component property will disable
the link-to
component.
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
component you can
override the global behaviour of Ember.LinkComponent
.
1 2 3 4 5 6 7 8 |
Ember.LinkComponent.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
router'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".
Keeping a link active for other routes
If you need a link to be 'active' even when it doesn't match
the current route, you can use the current-when
argument.
This may be helpful for keeping links active for:
- non-nested routes that are logically related
- some secondary menu approaches
- 'top navigation' with 'sub navigation' scenarios
A link will be active if current-when
is true
or the current
route is the route this link would transition to.
To match multiple routes 'space-separate' the routes:
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 |
Router.map(function() { this.route("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 |
Router.map(function() { this.route("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/comments/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 |
Router.map(function() { this.route("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.
Allowing Default Action
By default the {{link-to}}
component prevents the default browser action
by calling preventDefault()
as this sort of action bubbling is normally
handled internally and we do not want to take the browser to a new URL (for
example).
If you need to override this behavior specify preventDefault=false
in
your template:
Overriding attributes
You can override any given property of the Ember.LinkComponent
that is generated by the {{link-to}}
component by passing
key/value pairs, like so:
See Ember.LinkComponent for a
complete list of overrideable properties. Be sure to also
check out inherited properties of LinkComponent
.
Overriding Application-wide Defaults
{{link-to}}
creates an instance of Ember.LinkComponent
for rendering. To override options for your entire
application, reopen Ember.LinkComponent
and supply the
desired values:
1 2 3 4 |
Ember.LinkComponent.reopen({ activeClass: "is-active", tagName: 'li' }) |
It is also possible to override the default event in this manner:
1 2 3 |
Ember.LinkComponent.reopen({ eventName: 'customEventName' }); |
Parameters:
- routeName String
- context [Object]
- options [Object]
- Handlebars key/value pairs of options, you can override any property of Ember.LinkComponent
Returns:
- String
- HTML string
loc
(str)
public
Calls Ember.String.loc with the provided string. This is a convenient way to localize text within a template. For example:
1 2 3 |
Ember.STRINGS = { '_welcome_': 'Bonjour' }; |
1 2 3 |
<div class='message'> Bonjour </div> |
See Ember.String.loc for how to set up localized string references.
Parameters:
- str String
- The string to format.
log
(values)
public
log
allows you to output the value of variables in the current rendering
context. log
also accepts primitive types such as strings or numbers.
Parameters:
- values *
mut
(attr)
public
The mut
helper lets you clearly specify that a child Component
can update the
(mutable) value passed to it, which will change the value of the parent component.
This is very helpful for passing mutable values to a Component
of any size, but
critical to understanding the logic of a large/complex Component
.
To specify that a parameter is mutable, when invoking the child Component
:
The child Component
can then modify the parent's value as needed:
1 2 3 4 5 6 |
// my-child.js export default Component.extend({ click() { this.get('childClickCount').update(this.get('childClickCount').value + 1); } }); |
Additionally, the mut
helper can be combined with the action
helper to
mutate a value. For example:
The child Component
would invoke the action with the new click value:
1 2 3 4 5 6 |
// my-child.js export default Component.extend({ click() { this.get('clickCountChange')(this.get('childClickCount') + 1); } }); |
The mut
helper changes the totalClicks
value to what was provided as the action argument.
See a 2.0 blog post for
additional information on using {{mut}}
.
Parameters:
- attr [Object]
- the "two-way" attribute that can be modified.
outlet
(name)
public
The {{outlet}}
helper lets you specify where a child route will render in
your template. An important use of the {{outlet}}
helper is in your
application's application.hbs
file:
See templates guide for
additional information on using {{outlet}}
in application.hbs
.
You may also specify a name for the {{outlet}}
, which is useful when using more than one
{{outlet}}
in a template:
Your routes can then render into a specific one of these outlet
s by specifying the outlet
attribute in your renderTemplate
function:
1 2 3 4 5 6 7 |
// app/routes/menu.js export default Ember.Route.extend({ renderTemplate() { this.render({ outlet: 'menu' }); } }); |
See the routing guide for more
information on how your route
interacts with the {{outlet}}
helper.
Note: Your content will not render if there isn't an {{outlet}}
for it.
Parameters:
- name [String]
partial
(partialName)
public
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.
Parameters:
- partialName String
- The name of the template to render minus the leading underscore.
query-params
(hash)
Object
public
This is a helper to be used in conjunction with the link-to helper. It will supply url query parameters to the target route.
Example
Parameters:
- hash Object
- takes a hash of query parameters
Returns:
- Object
- A `QueryParams` object for `{{link-to}}`
render
(name, context, options)
String
public
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
- context Object?
- options Hash
Returns:
- String
- HTML string
textarea
(options)
public
{{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
selectionEnd
selectionStart
selectionDirection
wrap
readonly
autofocus
form
spellcheck
required
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> |
Actions
The helper can send multiple actions based on user events.
The action property defines the action which is send when the user presses the return key.
The helper allows some user events to send actions.
enter
insert-newline
escape-press
focus-in
focus-out
key-press
For example, if you desire an action to be sent when the input is blurred, you only need to setup the action name to the event name property.
See more about Text Support Actions
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 building a Bootstrap project where data-*
attributes are used, you can globally add support for a data-*
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: ['data-error'] }); |
Keep in mind when writing Ember.TextArea
subclasses that Ember.TextArea
itself extends Ember.Component
. Expect isolated component semantics, not
legacy 1.x view semantics (like controller
being present).
See more about Ember components
Parameters:
- options Hash
unbound
public
The {{unbound}}
helper disconnects the one-way binding of a property,
essentially freezing its value at the moment of rendering. For example,
in this example the display of the variable name
will not change even
if it is set with a new value:
Like any helper, the unbound
helper can accept a nested helper expression.
This allows for custom helpers to be rendered unbound:
The unbound
helper only accepts a single argument, and it return an
unbound value.
unless
public
The unless
helper is the inverse of the if
helper. Its block will be
rendered if the expression contains a falsey value. All forms of the if
helper can also be used with unless
.
view
deprecated
public
{{view}}
inserts a new instance of an 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.
1 2 3 4 |
var App = Ember.Application.create(); App.WithTemplateDefinedView = Ember.View.extend({ templateName: 'defined-template' }); |
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 |
with
(options)
String
public
Use the {{with}}
helper when you want to alias a property to a new name. This is helpful
for semantic clarity as it allows you to retain default scope or to reference a property from another
{{with}}
block.
If the aliased property is "falsey", for example: false
, undefined
null
, ""
, 0
, NaN or
an empty array, the block will not be rendered.
Without the as
operator, it would be impossible to reference user.name
in the example above.
NOTE: The alias should not reuse a name from the bound property path.
For example: {{#with foo.bar as |foo|}}
is not supported because it attempts to alias using
the first part of the property path, foo
. Instead, use {{#with foo.bar as |baz|}}
.
Parameters:
- options Object
Returns:
- String
- HTML string