使用Ember.js和Ember-data&Rails创建记录并处理记录列表

syn*_*sin 18 ruby-on-rails ember.js ember-data

我正在构建一个具有如下布局的应用程序.

预览http://sunshineunderground.kr/problem-01.png

我想创建一个新帖子,所以我按下了"新帖子按钮",它把我带到了"帖子/新帖".

My PostsNewRoute如下(我按照这里描述的方法)

 App.PostsNewRoute = Ember.Route.extend({
     model: function() {

           // create a separate transaction, 

           var transaction = this.get('store').transaction();

           // create a record using that transaction

           var post = transaction.createRecord(App.Post, {
                title: 'default placeholder title',
                body: 'default placeholder body'
           });

          return post;
     } 
 });
Run Code Online (Sandbox Code Playgroud)

它会立即创建新记录,更新帖子列表,并显示新帖子的表单.

预览http://sunshineunderground.kr/problem-02.png

现在我有两个问题.

一个是帖子列表的顺序.

我预计新帖子将位于列表的顶部,但它位于列表的底部.

我使用rails作为我的后端,并将Post模型顺序设置为

 default_scope order('created_at DESC')
Run Code Online (Sandbox Code Playgroud)

旧帖子位于现有帖子的下方.但新创建的不是.(尚未承诺后端)

另一个是当我点击列表中创建的帖子时

我可以在帖子列表中点击我新创建的帖子.它带我到一个带URL的帖子页面

 /posts/null
Run Code Online (Sandbox Code Playgroud)

这是我必须阻止的非常奇怪的行为.

我认为会有两种解决方案.

  1. 当我点击"新发布按钮"创建一条记录并立即提交服务器,当服务器成功保存我的新记录后,刷新帖子列表并进入新创建的帖子的编辑模式.

  2. 或者,当我点击PostsNewView中的"提交"按钮时,最初将Route的模型设置为null并创建记录.

  3. 或者只显示属性为的帖子

        'isNew' = false, 'isDirty' = false, 
    
    Run Code Online (Sandbox Code Playgroud)

在列表中..

但遗憾的是,我不知道从哪里开始......

对于解决方案1,我完全迷路了.

对于解决方案2,我不知道如何将输入表单中的数据绑定到尚未存在的模型.

对于解决方案3,我完全迷路了.

请帮我!这将是余烬的预定方式?

(我听说Ember打算为每个开发人员使用相同的解决方案)

更新

现在我正在使用解决方案3并仍然有订购问题.这是我的帖子模板代码.

    <div class="tools">
        {{#linkTo posts.new }}new post button{{/linkTo}}
    </div>
    <ul class="post-list">
        {{#each post in filteredContent}}
        <li>
            {{#linkTo post post }}
                <h3>{{ post.title }}</h3>
                <p class="date">2013/01/13</p>
                <div class="arrow"></div>
            {{/linkTo}}
        </li>
        {{/each}}
    </ul>
    {{outlet}}
Run Code Online (Sandbox Code Playgroud)

更新

我通过过滤'arrangeContent'解决了这个问题,而不是'内容'

 App.PostsController = Ember.ArrayController.extend({
   sortProperties: ['id'],
   sortAscending: false,
   filteredContent: (function() {

     var content = this.get('arrangedContent');

     return content.filter(function(item, index) {
       return !(item.get('isDirty'));
     });
   }).property('content.@each')

 });
Run Code Online (Sandbox Code Playgroud)

And*_*lan 8

我们在应用程序的几个地方使用了解决方案3的变体.恕我直言,它是3中最干净的,因为您不必担心服务器端的设置/拆卸这是我们实现它的方式:

App.PostsController = Ember.ArrayController.extend({
  sortProperties: ['id'],
  sortAscending: true,
  filteredContent: (function() {
    return this.get('content').filter(function(item, index) {
      return !(item.get('isDirty'));
    });
  }).property('content.@each')
});
Run Code Online (Sandbox Code Playgroud)

然后在Posts模板中循环通过controller.filteredContent而不是controller.content.

对于解决方案1,有许多可能性.您可以定义以下事件:

  createPost: function() {
    var post,
      _this = this;
    post = App.Post.createRecord({});
    post.one('didCreate', function() {
      return Ember.run.next(_this, function() {
        return this.transitionTo("posts.edit", post);
      });
    });
    return post.get("store").commit();
  }
Run Code Online (Sandbox Code Playgroud)

它创建帖子然后设置一个承诺,一旦"didCreate"在帖子上触发就会执行.此承诺仅在从服务器返回后才转换到帖子的路由,因此它将具有正确的ID.