Samat  Zhanbekov
Samat Zhanbekov

Reputation: 413

Adding child routes in ember.js

I'm working on ember.js tutorial now. I got a problem on "adding child routes" chapter. My todos list is not displayed. The "todos" template outputing just fine but "todos/index" template doesn't work at all. The console does not show any errors. I guess that this is some local problem or some bug. Maybe someone has already met with a similar problem. What could be the reason of this issue? How can i solve it? Thanks.

HTML:

<html>
  <head>
    <meta charset="utf-8">
    <title>Ember.js • TodoMVC</title>
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
   <script type="text/x-handlebars" data-template-name="todos/index">
    <ul id="todo-list">
      {{#each itemController="todo"}}
        <li {{bind-attr class="isCompleted:completed isEditing:editing"}}>
          {{#if isEditing}}
            {{edit-todo class="edit" value=title focus-out="acceptChanges" insert-newline="acceptChanges"}}
          {{else}}
            {{input type="checkbox" checked=isCompleted class="toggle"}}
            <label {{action "editTodo" on="doubleClick"}}>{{title}}</label><button {{action "removeTodo"}} class="destroy"></button>
          {{/if}}
        </li>
      {{/each}}
    </ul>
  </script>

  <script type="text/x-handlebars" data-template-name="todos">

    <section id="todoapp">
      <header id="header">
        <h1>todos</h1>
        {{input type="text" id="new-todo" placeholder="What needs to be done?" 
                value=newTitle action="createTodo"}}
      </header>

        <section id="main">
          {{outlet}}
          <input type="checkbox" id="toggle-all">
        </section>

        <footer id="footer">
          <span id="todo-count">
            <strong>{{remaining}}</strong> {{inflection}} left</span>
          <ul id="filters">
            <li>
              <a href="all" class="selected">All</a>
            </li>
            <li>
              <a href="active">Active</a>
            </li>
            <li>
              <a href="completed">Completed</a>
            </li>
          </ul>

          <button id="clear-completed">
            Clear completed (1)
          </button>
        </footer>
    </section>

    <footer id="info">
      <p>Double-click to edit a todo</p>
    </footer>

  </script>
    <script src="js/libs/jquery-1.10.2.js"></script>
    <script src="js/libs/handlebars-1.1.2.js"></script>
    <script src="js/libs/ember-1.2.0.js"></script>
    <script src="js/libs/ember-data.js"></script>
    <script src="js/app.js"></script>
    <script src="js/route.js"></script>
    <script src="js/models/todo.js"></script>
    <script src="js/controllers/todo_controller.js"></script>
    <script src="js/controllers/todos_controller.js"></script>
    <script src="js/views/edit_todo_view.js"></script>
  </body>
</html>

JS:

    window.Todos = Ember.Application.create();

    Todos.ApplicationAdapter = DS.FixtureAdapter.extend();
    Todos.Router.reopen({
      rootURL: '/one/'
    });

    Todos.Router.map(function () {
      this.resource('todos', { path: '/' });
    });

    Todos.TodosRoute = Ember.Route.extend({
      model: function () {
        return this.store.find('todo');
      }
    });

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

    Todos.Todo = DS.Model.extend({
        title:DS.attr('string'),
        isCompleted:DS.attr('boolean')
    });
    Todos.Todo.FIXTURES = [
      {
        id: 1,
        title: 'Learn Ember.js',
        isCompleted: true
      },
      {
        id: 2,
        title: '...',
        isCompleted: false
      },
      {
        id: 3,
        title: 'Profit!',
        isCompleted: false
      }
    ];
Todos.TodosController = Ember.ArrayController.extend({
  actions: {
    createTodo: function () {
      // Get the todo title set by the "New Todo" text field
      var title = this.get('newTitle');
      if (!title.trim()) { return; }

      // Create the new Todo model
      var todo = this.store.createRecord('todo', {
        title: title,
        isCompleted: false
      });

      // Clear the "New Todo" text field
      this.set('newTitle', '');

      // Save the new model
      todo.save();
    }
  },

  remaining: function () {
    return this.filterBy('isCompleted', false).get('length');
  }.property('@each.isCompleted'),

  inflection: function () {
    var remaining = this.get('remaining');
    return remaining === 1 ? 'item' : 'items';
  }.property('remaining'),

});

Todos.TodoController = Ember.ObjectController.extend({
  actions:{
     editTodo: function () {
       this.set('isEditing', true);
     },
     acceptChanges: function () {
        this.set('isEditing', false);

        if (Ember.isEmpty(this.get('model.title'))) {
          this.send('removeTodo');
        } else {
          this.get('model').save();
        }
      },

      removeTodo: function () {
        var todo = this.get('model');
        todo.deleteRecord();
        todo.save();
      },
   },

  isEditing: false,

  isCompleted: function(key, value){
    var model = this.get('model');

    if (value === undefined) {
      // property being used as a getter
      return model.get('isCompleted');
    } else {
      // property being used as a setter
      model.set('isCompleted', value);
      model.save();
      return value;
    }
  }.property('model.isCompleted')
});

Upvotes: 1

Views: 524

Answers (2)

Kingpin2k
Kingpin2k

Reputation: 47367

Technically this isn't a bug, the team figured there is no point in having an index route if you can't go any deeper in the router (this is due to the fact that the todos route and template will render, so there is no real need for the index route. That being said, if you really want it, add an anonymous function and you'll get it.

Todos.Router.map(function () {
  this.resource('todos', { path: '/' },function () {});
});

https://github.com/emberjs/ember.js/issues/3995

Upvotes: 5

therufs
therufs

Reputation: 25

I had this problem too. After much perplexity, the solution was to use a version of index.html that actually had the <script> wrapped <ul>, instead of the one where I was moving that block around to see if it made a difference and ended up having it nowhere.

Upvotes: 1

Related Questions