home
  • Blog
1.10
  • Getting Started
    • Getting Started
    • Planning The Application
    • Creating a Static Mockup
    • Obtaining Ember.js and Dependencies
    • Adding the First Route and Template
    • Modeling Data
    • Using Fixtures
    • Displaying Model Data
    • Displaying a Model's Complete State
    • Creating a New Model Instance
    • Marking a Model as Complete or Incomplete
    • Displaying the Number of Incomplete Todos
    • Toggling between Showing and Editing States
    • Accepting Edits
    • Deleting a Model
    • Adding Child Routes
    • Transitioning to Show Only Incomplete Todos
    • Transitioning to Show Only Complete Todos
    • Transitioning back to Show All Todos
    • Displaying a Button to Remove All Completed Todos
    • Indicating When All Todos Are Complete
    • Toggling All Todos Between Complete and Incomplete
    • Replacing the Fixture Adapter with Another Adapter
  • Getting Ember
  • Concepts
  • The Object Model
  • Application
  • Templates
  • Routing
  • Components
  • Controllers
  • Models
  • Views
  • Enumerables
  • Testing
  • Configuring Ember.js
  • Cookbook
  • Understanding Ember.js
  • Contributing to Ember.js
Old Guides - You are viewing the guides for Ember v1.10.0.
Go to v5.0.0

Adding Child Routes

Edit pencil

Next we will split our single template into a set of nested templates so we can transition between different lists of todos in reaction to user interaction.

In index.html move the entire <ul> of todos into a new template named todos/index by adding a new Handlebars template <script> tag inside the <body> of the document:

<!--- ... additional lines truncated for brevity ... -->
<body>
<script type="text/x-handlebars" data-template-name="todos/index">
  <ul id="todo-list">
    {{#each todo in model itemController="todo"}}
      <li {{bind-attr class="todo.isCompleted:completed todo.isEditing:editing"}}>
        {{#if todo.isEditing}}
          {{edit-todo class="edit" value=todo.title focus-out="acceptChanges" insert-newline="acceptChanges"}}
        {{else}}
          {{input type="checkbox" checked=todo.isCompleted class="toggle"}}
          <label {{action "editTodo" on="doubleClick"}}>{{todo.title}}</label><button {{action "removeTodo"}} class="destroy"></button>
        {{/if}}
      </li>
    {{/each}}
  </ul>
</script>
<!--- ... additional lines truncated for brevity ... -->

Still within index.html place a Handlebars {{outlet}} helper where the <ul> was previously:

{{! ... additional lines truncated for brevity ... }}
<section id="main">
  {{outlet}}

  <input type="checkbox" id="toggle-all">
</section>
{{! ... additional lines truncated for brevity ... }}

The {{outlet}} Handlebars helper designates an area of a template that will dynamically update as we transition between routes. Our first new child route will fill this area with the list of all todos in the application.

In js/router.js update the router to change the todos mapping, with an additional empty function parameter so it can accept child routes, and add this first index route:

Todos.Router.map(function () {
  this.resource('todos', { path: '/' }, function () {
    // additional child routes will go here later
  });
});

// ... additional lines truncated for brevity ...

Todos.TodosIndexRoute = Ember.Route.extend({
  model: function() {
    return this.modelFor('todos');
  }
});

When the application loads at the url '/' Ember.js will enter the todos route and render the todos template as before. It will also transition into the todos.index route and fill the {{outlet}} in the todos template with the todos/index template. The model data for this template is the result of the model method of TodosIndexRoute, which indicates that the model for this route is the same model as for the TodosRoute.

This mapping is described in more detail in the Naming Conventions Guide.

Live Preview

Ember.js • TodoMVC

Additional Resources

  • Changes in this step in diff format
  • Ember Router Guide
  • Ember Controller Guide
  • outlet API documentation
left arrow
Deleting a Model
Transitioning to Show Only Incomplete Todos
right arrow
On this page

  • Live Preview
  • Additional Resources
Team Sponsors Security Legal Branding Community Guidelines
Twitter GitHub Discord Mastodon

If you want help you can contact us by email, open an issue, or get realtime help by joining the Ember Discord.

© Copyright 2023 - Tilde Inc.
Ember.js is free, open source and always will be.


Ember is generously supported by
blue