在ember.js中添加子路由

时间:2013-12-24 15:38:06

标签: javascript ember.js handlebars.js

我正在研究ember.js教程。我在"adding child routes" chapter遇到了问题。我的待办事项列表未显示。 “todos”模板输出很好,但“todos / index”模板根本不起作用。控制台不显示任何错误。我想这是一些本地问题或一些bug。也许有人已经遇到过类似的问题。这个问题可能是什么原因?我怎么解决呢? 感谢。

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')
});

2 个答案:

答案 0 :(得分:5)

从技术上讲,这不是一个错误,团队认为如果你不能在路由器中更深入地进行索引路由没有意义(这是由于todos路由和模板将呈现,因此不需要索引路径。也就是说,如果你真的需要它,添加一个匿名函数,你就可以得到它。

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

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

答案 1 :(得分:1)

我也有这个问题。经过多次困惑之后,解决方案是使用一个版本的index.html实际上有<script>包裹<ul>,而不是我移动那个块的那个版本,看它是否有所作为,最终无处可去。