Ember.js如何扁平化async的许多关系

Ember.js how to flatten async hasMany relationships

本文关键字:许多 关系 async 扁平化 js Ember      更新时间:2023-09-26

假设我有一个这样的关系:

App.Library = DS.Model.extend
    authors = DS.hasMany(App.Author, {async: true})
App.Author = DS.Model.extend
    books: DS.hasMany(App.Book, {async: true)
App.Book = DS.Model.extend()

,我想从我的图书馆所有作者那里得到所有的书。如果这些不是Promises

我可以做一个简单的平铺样式操作

当两种关系都是异步的时候,我怎么做呢?

这是我想到的

allBooks: Ember.computed('authors', function() {
      var r = []
      this.get('authors').then(function(authors) {
          authors.forEach(function(author) {                  
              author.get('books').then(function(books) {
                  books.forEach(function(book){
                      r.push.apply(r, book);
                  });
              });
            });
      });
    return r;
}

:

我应该在早些时候说明这一点,但实际上我确实使用了下面的代码。但是现在,ArrayController已被弃用,我正在寻找其他方法来实现相同的结果。

 allBooks: Ember.computed('authors', function() {
      var allBooks  = Ember.ArrayController.create();
      this.get('authors').then(function(authors) {
          authors.forEach(function(author) {                  
              author.get('books').then(function(books) {
                  books.forEach(function(book){
                      allBooks.addObject(book);
                  });
              });
            });
      });
    return allBooks;
}

我想我可以这样做,有没有其他更好的方法?:

books: Ember.computed('authors', function() {
      var a  = Ember.Object.create({
          content: Ember.A()
      });
      this.get('authors').then(function(authors) {
          authors.forEach(function(author) {
              author.get('books').then(function(books) {
                  books.forEach(function(book){
                      a.get('content').addObject(book);
                  });
              });
            });
      });
    return a.get('content');
}),

你可以在你的路由中组装数组,在你的控制器中使用PromiseProxyMixin(或者其他一些附加到你的控制器的对象,如果你不想让它们作为主模型)。

// in route
setupController: function(controller, model) {
    var allBooksPromise = new Ember.RSVP.Promise(function (resolve, reject) {
        // get your books here
        var allBooks = ...
        resolve(allBooks);
    }
    controller.set('promise', allBooksPromise);
}
// in controller
export default Ember.Controller.extend(Ember.PromiseProxyMixin);
// in template
{{#if controller.isPending}}
    Getting all of the books...
{{else}}
    <ul>
    {{#each controller.content as |book|}}
       <li>{{book.title}}</li>
    {{/each}}
    </ul>
{{/if}}