18

以下のようなレイアウトのアプリを作っています。

プレビュー

新しい投稿を作成したいので、「新しい投稿ボタン」を押すと、「投稿/新しい」ルートに移動しました。

私の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;
     } 
 });

すぐに新しいレコードを作成し、投稿のリストを更新し、新しい投稿のフォームを表示します。

プレビュー
(出典:sunshineunderground.kr

今、私は2つの問題を抱えています。

1つは投稿リストの順序です。

新しい投稿がリストの一番上になると思っていましたが、リストの一番下にあります。

バックエンドとしてレールを使用しており、Postモデルの順序を次のように設定しています。

 default_scope order('created_at DESC')

そのため、古い投稿は既存の投稿内の下にあります。しかし、新しく作成されたものはそうではありません。(まだバックエンドにコミットされていません)

もう1つは、リストで作成された投稿をクリックしたときです。

投稿リストで新しく作成した投稿をクリックできます。そしてそれは私をURLのある投稿ページに連れて行った

 /posts/null

そしてそれは私が防がなければならない非常に奇妙な行動です。

2つの解決策があると思います。

  1. [新しい投稿]ボタンをクリックすると、レコードを作成してすぐにサーバーにコミットし、サーバーが新しいレコードを正常に保存したら、投稿リストを更新して、新しく作成した投稿の編集モードに入ります。

  2. または、最初にRouteのモデルをnullに設定し、PostsNewViewの[送信]ボタンをクリックしたときにレコードを作成します。

  3. またはshowは、属性がである投稿のみを表示します

        'isNew' = false, 'isDirty' = false, 
    

リストに..

しかし悲しいことに、私はどちらの方法から始めればよいのかわかりません...

解決策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}}

アップデート

'content'ではなく'arrangedContent'をフィルタリングすることでこの問題を解決しました

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

 });
4

3 に答える 3

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

次に、投稿テンプレートで、controller.contentではなくcontroller.filteredContentをループします。

解決策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();
  }

投稿を作成し、投稿で「didCreate」が起動すると実行されるPromiseを設定します。このPromiseは、サーバーから戻った後にのみ投稿のルートに移行するため、正しいIDが割り当てられます。

于 2013-02-05T11:05:48.090 に答える
3

確かに、とてもいい書き込みです。そのためのThx。

状態 iofilteredContentを使用する必要はありません。そうしないと、編集中の投稿が表示されません。どちらの場合も、私の場合、プロパティは機能しません。また、すべての要素の一部として画像を使用しているため、変更するとすべての画像が更新されることにも気付きました。これは、すべての画像に対するリクエストが表示されることを意味します。isNewisDirtyfilteredContentfilteredContent

私は少し異なるアプローチを使用します。コンテンツをループして、テンプレートに投稿を表示するかどうかを決定します。

# posts.handlebars
<ul class='posts'>
  {{#each controller}}
    {{#unless isNew}}
      <li>
        <h3>{{#linkTo post this}}{{title}}{{/linkTo}}</h3>
        <img {{bindAttr src="imageUrl"}}/>
        <a {{action deletePost}} class="delete-post tiny button">Delete</a>
      </li>
    {{/unless}}
  {{/each}}
</ul>

これは、保存後のPostオブジェクトのみを表示します。H3 タグの URL には、新しく作成されたオブジェクト io posts/nullの ID も含まれています。

あなたの質問で気付いたもう 1 つの点: デフォルト値を createRecord に渡す代わりに、モデル自体で defaultValues プロパティを使用できます。

したがって、代わりに:

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

あなたはこれを行うことができます:

# App.Post
App.Post = DS.Model.extend({
  title: DS.attr('string', {
    defaultValue: "default placeholder title"
  }),
  body: DS.attr('string', {
    defaultValue: "default placeholder body"
  })
});

# App.PostsNewRoute
var post = transaction.createRecord(App.Post);
于 2013-02-16T16:44:49.240 に答える
0

しばらく前に、コンテンツ配列を逆にする関数を実際に作成しました。

http://andymatthews.net/read/2012/03/20/Reversing-the-output-of-an-Ember.js-content-array

それはかなり古い記事で、ほぼ 1 年前のものなので、このままでは機能しない可能性がありますが、フレームワークはそこにあります...

私が書いたこのミニアプリで実際にそれを見ることができます:

http://andymatthews.net/code/emberTweets/

上部の入力フィールドでユーザーを検索し、(古いものから新しいものではなく) 新しいものから古いものの順に表示される左側を見てください。

于 2013-02-28T20:24:22.540 に答える