如何将项目父项添加到Ember-CLI TodoMVC?

时间:2015-02-10 23:59:26

标签: ember.js ember-cli todomvc

我正在使用Ember-CLI开发一个todo类型的项目。我用作漂亮的todoMVC项目的起点,但使用本指南使用Ember-CLI构建:

http://blaketv.com/2014/10/03/ember-cli-todo-mvc-tutorial-0-0-47//

我的问题是,如何在父级别添加项目。所以我们将有一个master-detail类型的界面,在侧边栏中我们有项目,你可以CRUD项目名称,然后当你点击项目名称时,你会看到详细信息窗格中的待办事项。

我已经远远地定义了与模型的hasMany关系,但我无法弄清楚我是否需​​要多个{{outlets}}很难将所有内容放在同一页面上并且正常工作。

这是我的项目模型:

export default DS.Model.extend({
  title: DS.attr('string'),
  isCompleted: DS.attr('boolean'),
  description: DS.attr('string'),
  todos: DS.hasMany('todo', {async: true})
});

和todos模型:

import DS from 'ember-data';

export default DS.Model.extend({
  title: DS.attr('string'),
  isCompleted: DS.attr('boolean')
});

和主路由器:

Router.map(function() {
  this.resource('projects', function () {
    this.route('new'); 
    this.resource('project', { path: ':id' }, function () {
      this.route('todos');
    });
  });
});

项目路线:

export default Ember.Route.extend({
  model: function(params) {
    return this.store.find('project', params.id);
  }
});

索引路线:

export default Ember.Route.extend({
  model: function() {
    return this.store.find('project');
  }
});

托多斯路线:

export default Ember.Route.extend({
  model: function() {
    return this.modelFor('todos');
  }
});

因此对于project.hbs而言,这是一个棘手的问题。我创建了带有bootsrap的侧边栏,然后这个插座显示了todos ....

<div class="projects-column col-md-3">
  <div id="inbox-header"><span class="glyphicon glyphicon-inbox"></span> Inbox <span class="badge">42</span></div>
  <div id="projects-header"><span class="glyphicon glyphicon-list-alt"></span> Projects</div>
  <div id="forecast-header"><span class="glyphicon glyphicon-calendar"></span> Forecast</div>
  <div id="log-header"><span class="glyphicon glyphicon-book"></span> Sessions Log</div>
</div>
  <div>{{outlet}}</div>

Index.hbs:

<ul>
  {{#each model}}
  <li>{{link-to title "project.todos" this}}</li>
 {{/each}}

所以当你点击项目标题链接时,它会显示相关的待办事项....但它会在左侧窗格中呈现......它可能只是关于CSS布局的东西......但有些东西告诉我那里是一种非常Ember-ish的方法来做到这一点,我错过了。

然后在/project/todo.hbs我们有迭代

{{#each model.todos}}
    <li>{{title}}</li>
{{/each}}

我甚至没有真正解决过控制器或任何东西的CRUD问题。最有可能上述情况是可笑的,有一种更优雅的方式来解决这个问题......

基本上我想要一个项目父路线,我用它做CRUD ......然后当你在侧边栏中渲染项目链接列表并单击一个时,你会在右侧窗格中看到渲染的ToDoMVC工作应用程序。

当然这只是我申请的起点。最有可能的是,如果有人想出一个优雅的方法,我们可以把它变成github上的一个开源项目,供其他人学习。

我认为一群新兴的ember开发人员在使用这种类型的东西时遇到了困难,因为有多种方法(插件,局部,渲染,渲染到其他模板,视图,组件等)

真的不知道如何进一步。

1 个答案:

答案 0 :(得分:0)

不确定你是否仍然卡住了,但是我会尝试不使用bootstrap作为侧边栏,只需输入{{#each}} [完整代码]

App = Ember.Application.create({
  LOG_TRANSITIONS: true,
  LOG_BINDINGS: true,
  LOG_VIEW_LOOKUPS: true,
  LOG_ACTIVE_GENERATION: true,
  debugMode: true
});

App.Router.map(function() {
  this.resource('projects', {
    path: '/'
  });
  this.resource('project', {
    path: '/projects/:project_id'
  }, function() {
    // URL = '/projects/:id/todos'
    this.resource('project.todos', {
      path: '/todos'
    }, function() {
      // URL = '/project/:id/todos/new'
      this.route("new");
    });

  });
});
App.ApplicationAdapter = DS.FixtureAdapter.extend();
//App.Store = DS.Store.extend({adapter : DS.FixtureAdapter});

App.ProjectsRoute = Ember.Route.extend({
  model: function() {
    return this.store.findAll('project');
  },
  actions: {
    addproject: function() {
      var newproject = this.store.createRecord('project', {
        name: "My New project"
      });
    },
    removeproject: function(project) {
      console.log(project);
      console.log(this.controller.get("model"));
      this.controller.get("model").removeObject(project);
    }
  }
});

App.ProjectRoute = Ember.Route.extend({
  model: function(params) {
    return this.store.find('project', params.project_id).then(function(project) {
      return project;
    });
  }

});
App.ProjectsIndexRoute = Ember.Route.extend({
  model: function(params) {
    return this.modelFor('project');
  }
});

App.ProjectTodosRoute = Em.Route.extend({

  model: function(params) {
    return this.modelFor('project');

  },
  actions: {
    addtodo: function() {
      this.transitionTo("project.todos.new");
    }
  }

});
App.projecttodosNewRoute = Em.Route.extend({
  model: function(params) {
    parentprojectId = this.modelFor('project').get("id");

    newtodo = this.store.createRecord('todo', {
      id: "5",
      name: "John Doe",
      //project : parentprojectId
      project: this.store.getById('project', parentprojectId)


    });
    console.log("new todo = " + newtodo);
    return newtodo;

  },
  actions: {
    save: function() {
      //console.log(this.controllerFor('projecttodosNew').content);
      //console.log('save of newtodo = '+this.controllerFor('projecttodosNew').get('newtodo'));
      console.log('newtodo~ ' + newtodo.get('name') + ', ' +
        newtodo.id + ', ' + newtodo);
      newtodo.save()
        //this.controllerFor('projecttodosNew').content.save()
        .then(function() {
          this.transitionTo("project.todos");
        });

    },
    cancel: function() {
      console.log("rollback for " + this.get("controller.model"));
      this.get("controller.model").rollback();
      this.set("controller.model", null);
      this.transitionTo("project.todos");
    }
  }
});

//App.projecttodosNewController = Ember.ObjectController
//			.extend({
//				needs : [ 'application', 'project'],
//				newtodo : null
//    });
App.Project = DS.Model.extend({
  name: DS.attr(),
  todos: DS.hasMany('todo', {
    async: true
  })
});

App.Project.FIXTURES = Em.A([{
  id: 1,
  name: 'Monday',
  todos: ['2']
}, {
  id: 2,
  name: 'Tuesday',
  todos: ['1', '2']
}, {
  id: 3,
  name: 'Wednesday',
  todos: ['4']
}]);

App.Todo = DS.Model.extend({
  name: DS.attr('string'),
  //project : DS.belongsTo('project')
});
App.Todo.FIXTURES = [{
  id: 1,
  name: 'shop',
  project: 1
}, {
  id: 2,
  name: 'sell things',
  project: 2
}, {
  id: 4,
  name: 'dance',
  project: 3
}];
/* Put your CSS here */

html,
body {
  margin: 20px;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Ember Starter Kit</title>
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css">
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
  <script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"></script>
  <script src="http://builds.emberjs.com/tags/v1.6.1/ember.js"></script>
  <script src="http://builds.emberjs.com/tags/v1.0.0-beta.10/ember-data.prod.js"></script>

</head>

<body>
  <script type="text/x-handlebars">
    <h2>Welcome to "The Project/TODO Demo"</h2>
    {{outlet}}
  </script>

  <script type="text/x-handlebars" data-template-name="projects">
    <ul>
      {{#each item in model}}
      <li>{{#link-to 'project.todos' item }}{{item.name}}, List of todos{{/link-to}} ,
        <button {{action "removeproject" item}}>X</button>
      </li>
      {{/each}}

    </ul>
    <button type="button" {{action "addproject" this.id}}>Add a project</button>
    {{outlet}}
  </script>
  <script type="text/x-handlebars" data-template-name="project/index">
    <br><b>Name of project:</b> {{name}}

  </script>
  <script type="text/x-handlebars" data-template-name="project">
    {{#link-to "projects"}}Home{{/link-to}} {{outlet}}
  </script>
  <script type="text/x-handlebars" data-template-name="project/todos/index">
    <h1></h1>
    <b>todos</b> 
    <br>
    <ul>
      {{#each todo in todos}}
      <li>{{todo.name}}</li>
      {{/each}}
    </ul>
    <button type="button" {{action "addtodo"}}>Add a todo</button>
    <br>{{#link-to 'project' this}}project details page{{/link-to}} {{outlet}}
  </script>
  <script type="text/x-handlebars" data-template-name="project/todos/new">
    <h1></h1>
    <b>New todos</b> 
    <br>
    <ul>
      <li>Name: {{input type='text' value=model.name}}</li>
      <li>todo Id: {{input type='text' value=id}}</li>
      <li>Parent project Id: {{project}}</li>
    </ul>
    <button type="button" {{action "save"}}>Save todo</button>
    <button type="button" {{action "cancel"}}>cancel</button>
    <br>{{outlet}}
  </script>
</body>

</html>

位于首页/索引的顶部。在你开始工作之后,你可以开始使用bootstrap进行布局,并让它看起来很酷。

类似于links doc。希望能让你通过障碍。