【问题标题】:When does the model() hook in the route handler get called anyway? Does it get called in a link-to in Ember.js?路由处理程序中的模型()钩子什么时候被调用?它是否在 Ember.js 的链接中被调用?
【发布时间】:2025-11-26 11:30:01
【问题描述】:

我在教程中在线阅读了这篇文章:

因为我们为链接 (book.author) 提供了一个模型,所以 Ember 不是 调用 model() 钩子,因此没有问题 重新加载数据。我们的解决方法很简单:传入 book.author.id 所以 该模型()被调用。

我正在尝试覆盖 author.js 适配器中的 shouldBackgroundReloadRecord 钩子,我认为只有在使用 findRecord 调用 model() 钩子时才会调用它......但我从来没有看到让我思考的 console.log 消息模型钩子没有在路由处理程序中被调用:

商店使用此方法来确定商店是否应该 在 store.findRecord 方法解析缓存后重新加载记录 记录。

只有当商店返回一个 缓存记录。

如果此方法返回 true,则商店将从 适配器。

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({

  shouldReloadRecord(store, snapshot) {
    return false;
  },

  shouldBackgroundReloadRecord(store, snapshot) {
    console.log("Calling shouldBackgroundReloadRecord");
    const loadedAt = snapshot.record.get('loadedAt');

    // if it was loaded more than an hour ago
    if (Date.now() - loadedAt > 3600000) {
      return true;
    } else {
      return false;
    }
  }

});

这是我的模板/books.hbs,带有链接:

{{!-- app/templates/books.hbs --}}
...
{{#link-to 'author' book.author.id class="author" bubbles=false }}{{book.author.name}}{{/link-to}}
...

据我了解,每当我们点击一​​个链接时,我们都会点击 router.js,然后由它决定调用哪个路由处理程序。当路由处理程序被调用时,模型()钩子不会在路由处理程序中被调用吗?

我的作者路由处理程序很正常,可能很不相关,但就是这样。

import Ember from 'ember';

export default Ember.Route.extend({
  model(params) {
    return this.store.findRecord('author', params.author_id);
  }
});

【问题讨论】:

    标签: ember.js


    【解决方案1】:

    我建议你查阅Ember.Route#model 文档:

    请注意,对于具有动态段的路由,此挂钩并不总是被执行。如果路由是通过转换进入的(例如,当使用链接到 Handlebars 助手或路由的 transitionTo 方法时),并且已经提供了模型上下文,则不会调用此钩子。

    模型上下文不包含原始字符串或数字,这会导致调用模型挂钩。

    随后是代码示例以及它们是否触发模型挂钩。

    【讨论】:

      【解决方案2】:

      当您通过链接更改查询参数时,它不会被视为完全转换。这意味着不会调用类似模型的 Route 方法钩子。 如果您需要更改查询参数以触发完整转换,因此方法挂钩,您可以在 Route 上使用可选的 queryParams 配置哈希。如果您有一个 authoerId 查询参数并且希望它触发模型刷新,则可以将其设置为

      //路线

      import Route from '@ember/routing/route';
      
      export default Route.extend({
        queryParams: {
          authorId: {
            refreshModel: true
          }
        },
      
        model({ authorId }) {
          return this.store.findRecord('author', authorId);
        }
      });
      

      // 控制器

      import Controller from '@ember/controller';
      
      export default Controller.extend({
        queryParams: ['authorId'],
        authorId: null
      });
      

      【讨论】:

        最近更新 更多