【问题标题】:Ember.js 2. Lazy fetch in background after rendering the pageEmber.js 2. 渲染页面后后台延迟获取
【发布时间】:2017-06-27 10:30:51
【问题描述】:

我有一个显示作者列表的简单页面“authors”。

每个作者当然有很多书,但在那个页面(和 API)我没有显示(/include ) 任何图书数据。

在作者路线中,我有默认的模型():

model() {
  return this.store.findAll('author');
}

一切正常。

现在我需要 一些东西,从其他 API(书籍的 API)获取惰性在后台)一些数据。

但我不希望此调用阻止我的作者页面呈现。所以,我有默认且快速的beforeModel()model()afterModel(),没有任何获取(作者数据除外)。

仅在页面呈现后我需要调用“api/books?author:1,2,3,4,5...”的东西(可能是服务?

这样,当有人点击作者时,我的“商店”中已经有了这些书(该书页中没有等待加载程序)。

如何做到这一点?

【问题讨论】:

    标签: javascript ember.js ember-data lazy-loading ember-cli


    【解决方案1】:

    1。如果您想在不阻塞 UI 的情况下延迟加载和存储关系数据:

    如果您不想显示延迟加载的关系数据(特别是hasMany-relationships),我建议在afterModel-hook 中这样做:

    route.js

      // ...
    
      afterModel(authors) {
        let lastPromise = new Promise(function(resolve) { resolve(); });
        authors.forEach(author => {
          lastPromise = lastPromise.then(() => {
            return author.get('books');
          });
        });
      },
    
      // ...        
    

    2。如果您想在不阻塞 UI 的情况下延迟加载、存储和显示关系数据:

    有几种方法可以做到这一点。延迟加载数据时我更喜欢的一种方式如下:

    首先,我创建一个组件来封装我的数据的显示和加载。在您的示例中,我将调用我的组件book-shelf

    在插入 DOM 后,我的组件想要显示其书籍。请参阅以下代码。

    component.js

    import Ember from 'ember';
    
    const {
      get,
      computed,
      ArrayProxy,
      PromiseProxyMixin,
      inject: { service }
    } = Ember;
    
    const ArrayPromiseProxy = ArrayProxy.extend(PromiseProxyMixin);
    
    export default Ember.Component.extend({
      // API:
      author: null,
    
      // Internal:
      store: service(),
      books: computed(
        'author.id',
        function() {
          if(!get(this, 'author.id')) {
            return [];
          }
          return ArrayPromiseProxy.create({
            promise: get(this, 'store').query('book', { authorId: get(this, 'author.id') })
          });
        }
      ),
    });
    

    在你的 template.hbs 中:

    <div class="book-shelf">
      {{#if books.isFulfilled}}
        Books of {{author.name}}:
        <ul>
          {{#each books as |book|}}
            <li>{{book.name}}</li>
          {{/each}}
        </ul>
      {{else}}
        Loading... please wait...
      {{/if}}
    </div> 
    

    这种方法将数组代理与 Promise 代理相结合,以便像数组一样工作,但还提供有关数据是否已加载的信息。

    您可以将此组件用作 ember.js 中的每个组件:

    {{book-shelf author=mySpecialAuthor}}
    

    【讨论】:

    • 非常感谢@Timm,但我不需要在 DOM 中,也不是在组件中。在作者页面中,我需要(仅在作者页面渲染之后)在后台获取书籍数据。这样每个作者的书籍数据就可以点击任何作者(以及书籍页面渲染......)。
    • 所以也许新添加的“第一”解决方案对您有用?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多