#Relevent parts to explain action, routes in Ember 1.0pre
##Action Helper
The {{action}}
helper registers an HTML element within a template for
DOM event handling and forwards that interaction to the Application's router,
the template's Ember.View
instance, or supplied target
option (see 'Specifiying a Target').
User interaction with that element will invoke the supplied action name on
the appropriate target.
(Example without Router skipped, check helpers/action.js)
There are several possible target objects for {{action}}
helpers:
In a typical Ember.Router
-backed Application where views are managed
through use of the {{outlet}}
helper, actions will be forwarded to the
current state of the Applications's Router. See Ember.Router 'Responding
to User-initiated Events' for more information.
If you manaully set the target
property on the controller of a template's
Ember.View
instance, the specifed controller.target
will become the target
for any actions. Likely custom values for a controller's target
are the
controller itself or a StateManager other than the Application's Router.
If the templates's view lacks a controller property the view itself is the target.
Finally, a target
option can be provided to the helper to change which object
will receive the method call. This option must be a string representing a
path to an object:
<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
.
The first argument to this method will be a jQuery.Event
extended to
include a view
property that is set to the original view interacted with.
A path relative to the template's Ember.View
instance can also be used as
a target:
<script type="text/x-handlebars" data-template-name='a-template'>
<div {{action anActionName target="parentView"}}>
click me
</div>
</script>
Clicking "click me" in the rendered HTML of the above template will trigger
the anActionName
method of the view's parent view.
The {{action}}
helper is Ember.StateManager
aware. If the target of the
action is an Ember.StateManager
instance {{action}}
will use the send
functionality of StateManagers. The documentation for Ember.StateManager
has additional information about this use.
If an action's target does not implement a method that matches the supplied action name an error will be thrown.
<script type="text/x-handlebars" data-template-name='a-template'>
<div {{action aMethodNameThatIsMissing}}>
click me
</div>
</script>
With the following application code
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.
During application initialization Ember will detect properties of the application ending in 'Controller', create singleton instances of each class, and assign them as properties on the router. The property name will be the UpperCamel name converted to lowerCamel format. These controller classes should be subclasses of Ember.ObjectController, Ember.ArrayController, Ember.Controller, or a custom Ember.Object that includes the Ember.ControllerMixin mixin.
App = Ember.Application.create({
FooController: Ember.Object.create(Ember.ControllerMixin),
Router: Ember.Router.extend({ ... })
});
App.get('router.fooController'); // instance of App.FooController
The controller singletons will have their namespace
property set to the application and their target
property set to the application's router singleton for easy integration with Ember's user event system.
See 'Changing View Hierarchy in Response To State Change' and 'Responding to User-initiated Events.'
Controller instances injected into the router at application initialization have their target
property
set to the application's router instance. These controllers will also be the default context
for their
associated views. Uses of the {{action}}
helper will automatically target the application's router.
Given the following application entered at the URL '#/':
App = Ember.Application.create({
Router: Ember.Router.extend({
root: Ember.Route.extend({
aRoute: Ember.Route.extend({
route: '/',
anActionOnTheRouter: function(router, context) {
router.transitionTo('anotherState', context);
}
})
anotherState: Ember.Route.extend({
route: '/differentUrl',
connectOutlets: function(router, context) {
}
})
})
})
});
App.initialize();
The following template:
<script type="text/x-handlebars" data-template-name="aView">
<h1><a {{action anActionOnTheRouter}}>{{title}}</a></h1>
</script>
Will delegate click
events on the rendered h1
to the application's router instance. In this case the
anActionOnTheRouter
method of the state at 'root.aRoute' will be called with the view's controller
as the context argument. This context will be passed to the connectOutlets
as its second argument.
Different context
can be supplied from within the {{action}}
helper, allowing specific context passing
between application states:
<script type="text/x-handlebars" data-template-name="photos">
{{#each photo in controller}}
<h1><a {{action showPhoto photo}}>{{title}}</a></h1>
{{/each}}
</script>
See Handlebars.helpers.action for additional usage examples.
Ref 1: https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/router.js
Ref 2: https://github.com/emberjs/ember.js/blob/master/packages/ember-handlebars/lib/helpers/action.js
Nice work, really helpful! :)