The contents of this gist are no longer up to date and do not reflect changes in thinking and implementation since it was created.
A component is a triple of:
- A template
- A controller (for a model)
- A view
A component name represents all aspects of this triple, looked up via a container:
container.lookup('template:<name>')
container.lookup('controller:<name>')
container.lookup('view:<name>')
By default, the template for a component is a template which does not modify the buffer.
By default, the view for a component is the DefaultView
, which is a simple
virtual (Metamorph
) view.
By default, the controller for a component depends on the model:
- If the model is an object, the controller is a generated
ObjectController
- If the model implements
Ember.Array
, the controller is a generatedArrayController
- Otherwise, the controller is a generated
Controller
A component is always built in the context of a container. The operations that generate a component may use different containers.
{{render "<name>" <model>?}}
- if
<model>
is specified, let model be the result of evaluating<model>
in the current template context. - otherwise, let model be undefined.
- let container be the container for the current controller.
- let view be the result of evaluating the algorithm Build a Component
with the parameters container,
<name>
, and model. - append view to the current view.
{{control "<name>" <model>?}}
- if
<model>
is specified, let model be the result of evaluating<model>
in the current template context. - otherwise, let model be undefined.
- let parentContainer be the container for the current controller.
- let key be the controlID for the
{{control}}
helper. - let container be the result of evaluating the algorithm Retrieve a Child Container with the arguments parentContainer,
- let view be the result of evaluating the algorithm Build a Component
with the parameters container,
<name>
, and model. - append view to the current view.
this.render("<name>")
This algorithm inherits a container from its calling context.
This algorithm assumes an outletView (a subclass of ContainerView
,
determined from other parameters and ambient state).
This algorithm assumes that previous code has already generated and populated
the controller for <name>
, so a lookup for controller:<name>
on container
will always succeed.
- let view be the result of evaluating the algorithm Build a Component
with the parameters container,
<name>
and undefined (for model). - set the
'currentView'
property of outletView to view.
{{#each <model> render="<name>"?}}
or {{each <model> render="<name>"?}}
- if model does not implement
Ember.Array
, throw an exception. - if
<name>
is not specified and there is no inline template supplied by the template engine, throw an exception. - if an inline template is supplied by the templating engine, let template be that template
- otherwise, let template be undefined.
- let model be the result of evaluating
<model>
in the current template context. - let parentView be the current view.
- let controller be the current controller.
- let parentContainer be the container for the current controller.
- let view be a new virtual (
Metamorph
) instance of Ember.CollectionView. - let the current view be view.
- let key be the controlID for the
{{each}}
helper - let containerList be the result of evaluating the algorithm Retrieve a Container List with the parameters controller and key.
- Evaluate the algorithm Render a List with the parameters
parentContainer,
<name>
, template, model, and containerList. - append view to parentView.
This algorithm takes parentContainer, name, template, model, and containerList as parameters.
- if model does not implement
Ember.Array
, throw an exception. - for each item in model with index i:
- let container be the item at position i in containerList.
- if container is undefined
- let container be a new child container for parentContainer.
- insert container in containerList at position i.
- let view be the result of evaluating the algorithm Build a Component with the parameters container, name, item, and template.
- append view to the current view.
- when an item is removed from the model array, destroy the container at the same position in containerList and destroy the view created by 2.3.
- when an item is added to the model array, follow 2 for the new item; the containers in the containerList should reflect their associated items in the model.
This algorithm takes parentContainer, controller, and key as parameters.
- let containers be an internal map of child containers for controller.
- let container be the container for key in containers.
- if container is not undefined, return container.
- let container be a new child container for parentContainer.
- insert container into containers for key.
- when the
'model'
property of controller changes, destroy container and delete key from the internal map of child containers. - return container.
This algorithm takes controller, and key as parameters.
- let containers be an internal map of child containers for controller.
- let containerList be the container list for key in containers.
- if containerList is not undefined, return containerList.
- let containerList be a new container list.
- insert containerList into containers for key.
- when the
'model'
property of controller changes, destroy all containers in containerList and delete key from the internal map of child containers - return containerList.
This algorithm takes container, name, and model as parameters.
This algorithm takes template as an optional parameter.
If name is undefined:
- if template is undefined, throw an exception.
- if model is undefined, let childController be a new, anonymous subclass
of
Ember.Controller
- let view be an instance of a new, anonymous subclass of
Ember._Metamorph
.
If name is not undefined:
- let childController be the result of looking up
'controller:<name>'
on container. - if childController is undefined, then childController is the result of evaluating Generate a Controller with the parameters container and model and name.
- set the
'model'
property of childController to model. - if template is undefined, late template be the result of looking up
'template:<name>'
on container. - if template is still undefined, let template be a new function that returns the empty string.
- let view be the result of looking up
'view:<name>'
on container. - if view is undefined, let view be an instance of a new, anonymous
subclass of
Ember._Metamorph
.
In either case, continue as follows:
- set the
'controller'
property of view to childController. - set the
'target'
property of childController to controller. - set the
'template'
property of view to template. - return view.
This algorithm takes container, model and name as parameters.
- If model implements
Ember.Array
, let controllerClass be a new, anonymous subclass ofEmber.ArrayController
- Otherwise, if model is not
null
,undefined
,false
, the empty string or 0, let controllerClass be a new, anonymous subclass ofEmber.ObjectController
- Otherwise, let controllerClass be a new, anonymous subclass of
Ember.Controller
- register controllerClass as the factory for
controller:<name>
on container. - return the result of looking up
controller:<name>
on container.