tworzenie rekordu z Ember.js & Ember-data & Rails i obsługa listy rekordów

Buduję aplikację, która ma układ jak poniżej.

Podgląd http://sunshineunderground.kr/problem-01.png

Chcę utworzyć nowy post, więc nacisnąłem 'new post button' i zabrało mnie do' posts/new ' trasa.

Moje PostsNewRoute jest jak poniżej (zastosowałem metodę opisaną tutaj)

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

Natychmiast tworzy nowy rekord, aktualizuje listę postów i wyświetla formularze dla nowego postu.

Podgląd http://sunshineunderground.kr/problem-02.png

Teraz mam dwa problemy.

Jednym z nich jest kolejność listy postów.

Spodziewałem się, że nowy post będzie na szczycie listy, ale jest na dole listy.

Używam rails jako zaplecza i ustawiam kolejność modelu posta na

 default_scope order('created_at DESC')

Więc stary Post znajduje się poniżej w istniejących postach. ale nowo utworzony nie jest. (który nie jest jeszcze przypisany do backendu)

Innym jest kiedy klikam utworzony post na liście

Mogę kliknąć mój nowo utworzony post na liście postów. i zaprowadziło mnie do strony posta z adresem URL

 /posts/null
I to bardzo dziwne zachowanie, któremu muszę zapobiec. Myślę, że będą dwa rozwiązania.
  1. Po kliknięciu "new post button" Utwórz rekord i zatwierdź do serwera natychmiast, a gdy serwer pomyślnie zapisał mój nowy rekord, Odśwież listę postów i wejdź w tryb edycji nowo utworzonego poczta.

  2. Lub wstępnie ustawić model trasy na null i utworzyć rekord, gdy kliknę przycisk "Wyślij" w widoku PostsNewView.

  3. Lub Pokaż Pokaż tylko posty, których atrybutem jest

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

Na liście..

Ale niestety nie wiem od czego zacząć...

Dla rozwiązania 1, całkowicie się gubię.

Dla rozwiązania 2, Nie wiem, jak powiązać dane w formularzach wejściowych z jeszcze nie istniejącym modelem.

Dla rozwiązania 3, całkowicie spadaj.

Proszę, pomóż mi! jaki będzie zamierzony sposób Embera? Ember ma używać tego samego rozwiązania dla każdego dewelopera.]}

Update

Teraz używam rozwiązania 3 i nadal mam problem z zamówieniem. Oto Mój kod szablonu postów.

    <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}}

Update

Rozwiązałem ten problem filtrując 'arrangedContent', a nie 'content'

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

 });
Author: synthresin, 2013-02-05

3 answers

Używamy wariantu rozwiązania 3 w kilku miejscach naszej aplikacji. IMHO jest najczystszy z 3 Jak nie musisz sie martwic o konfiguracje / tearddown po stronie serwera tak to zaimplementujemy:

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

Następnie w szablonie postów przechodzisz przez kontroler.filteredContent zamiast controller.treść.

Dla rozwiązania 1 Istnieje wiele możliwości. Można zdefiniować następujące zdarzenie:

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

Tworzy post, a następnie ustawia obietnicę, która zostanie wykonana raz" didCreate " strzela na słupie. Ta obietnica przechodzi na trasę posta dopiero po powrocie z serwera, więc będzie miał poprawne ID.

 8
Author: Andre Malan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-05 14:22:05

Rzeczywiście, bardzo ładnie napisać. Thx za to.

Czy Twój filteredContent nie musi używać isNew Stan i.o. isDirty, w przeciwnym razie Post, który jest edytowany, nie będzie widoczny. W obu przypadkach Właściwość filteredContent nie działa w moim przypadku. Zauważyłem również, że ponieważ używam obrazu jako części każdego elementu, Wszystkie obrazy zostaną odświeżone po zmianie filteredContent. Oznacza to, że widzę prośbę o każdy obraz.

Stosuję nieco inne podejście. I loop through the content i zdecydować, czy wyświetlać Post w szablonie:

# 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>

To pokaże tylko Post obiekt Po zostanie zapisany. Adres url w tagu H3 zawiera również id nowo utworzonego obiektu i.O. posts/null.

Jeszcze jedna rzecz, którą zauważyłem w twoim pytaniu: zamiast przekazywać wartości domyślne do createRecord, możesz użyć właściwości defaultValues w samym modelu:

Więc zamiast:

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

Możesz zrobić to:

# 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);
 3
Author: bazzel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-16 17:48:01

Napisałem funkcję odwracającą tablicę treści jakiś czas temu:

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

To dość stary artykuł, prawie rok, więc pewnie nie będzie działał tak jak jest, ale framework jest...

Możesz zobaczyć go w akcji w tej mini-aplikacji, którą napisałem:

Http://andymatthews.net/code/emberTweets/

Wyszukiwanie użytkowników w polu wprowadzania na górze i obserwuj lewą stronę w kolejności od najnowszego do najstarszego (zamiast od najstarszego do najnowszego).

 0
Author: commadelimited,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-28 20:24:22