Ember.js:并行加载父模型和子模型

Ember.js:并行加载父模型和子模型,ember.js,ember-data,Ember.js,Ember Data,我有以下路线: 职位 索引(所有员额) 单个(带有动态参数post_id) 索引(单个帖子及其评论视图) 编辑(编辑帖子) 有两个单独的请求用于按ID获取帖子和按帖子ID获取帖子注释。 我想并行加载posts.single.index路线的帖子和评论,因为我在路线名称中有一个帖子ID,我不必等待何时加载帖子 但是余烬加载posts.single模型,并且仅在post之后加载评论 可以同时调用子模型和父模型吗 当posts.single不加载任何内容,并且posts.single.in

我有以下路线:

  • 职位
    • 索引(所有员额)
    • 单个(带有动态参数post_id)
      • 索引(单个帖子及其评论视图)
      • 编辑(编辑帖子)
有两个单独的请求用于按ID获取帖子和按帖子ID获取帖子注释。 我想并行加载posts.single.index路线的帖子和评论,因为我在路线名称中有一个帖子ID,我不必等待何时加载帖子

但是余烬加载posts.single模型,并且仅在post之后加载评论

可以同时调用子模型和父模型吗


posts.single不加载任何内容,并且posts.single.index在它自己的模型中调用两个请求时,我找到了一个解决方案。另一方面,我应该在所有posts.single子路由中加载post模型,例如posts.single.edit。当应用程序增长时,这可能是一个问题。

有几种技术可以在路由的
模型中加载多个资源。哪一个最适合您的需要,或者哪一个是可能的,这在很大程度上取决于您的应用程序。特别是所使用的后端API的功能,以及您的Ember应用程序是否使用或普通/ajax请求,会产生很大的不同

最简单的情况是将Ember数据与REST API一起使用,REST API遵循并支持:

从“@ember/routing/Route”导入路由;
导出默认路由。扩展({
模型({post_id}){
返回this.store.findRecord('post',post_id,{include:'comments'});
}
});
如果您使用的是普通的
fetch
,则可以使用
Promise.all()
并行加载多条记录:

从“@ember/routing/Route”导入路由;
导出默认路由。扩展({
异步模型({post_id}){
让[张贴,评论]=等待承诺([
获取(`/posts/${post\u id}`),
获取(`/posts/${post\u id}/comments`),
]);
返回{post,comments};
}
});
如果您不喜欢带有数组破坏的
Promise.all()
语法,您可能需要看看<默认情况下,code>rsvp
与余烬绑定

如果使用Ember数据执行此操作,但您的API不支持侧向加载,则需要使用查询来加载注释,这有点棘手。这取决于您的适配器配置,但我想它应该是这样的:

从“@ember/routing/Route”导入路由;
导出默认路由。扩展({
异步模型({post_id}){
让[张贴,评论]=等待承诺([
此.store.findRecord('post',post\u id),
this.store.query('comment'{
过滤器:{
post:post\u id
}
})
]);
返回{post,comments};
}
});
不能使用多个
模型
-hook并行加载资源<代码>模型-父路由和子路由的挂钩按设计顺序执行。子路由的
model
-Hook在父
model
-Hook返回的
Promise
解决之前不会被激发。尽管如此,仍然有一些技术只加载所需的数据并缓存不同子路由之间共享的数据

让我们以你的问题为例,在这个答案的评论中有更详细的说明:我们的前端应该显示一个帖子,包括它在一条路线上的评论,以及一个表单来编辑另一条路线上的相同帖子。两条路线都需要相同的帖子资源,但只有一条路线还需要帖子的评论。如果用户从一个路由转换到另一个路由,应用程序不应再次加载帖子;如果用户转换到编辑视图,应用程序不应加载注释

天真的尝试是加载
post
资源的父路由和两个子路由,一个用于包含注释的视图,另一个用于编辑表单。我称这种尝试为“幼稚”,因为它在三个方面都失败了:

  • 帖子和评论不是并行加载的
  • 如果用户通过第三条路由在路由之间切换,则不会缓存资源
  • 它将可视化设计与数据加载相结合
  • 第三点可能令人困惑。事实上,这是对Ember中嵌套路由的常见误解。它们不是用来对数据层次结构建模,而是用来在子例程之间共享可视化UI。重要的不是
    模型
    -Hook,而是在父级的
    {{outlet}
    中呈现子模板

    您所有的问题都可以通过缓存客户端资源的服务轻松解决。这是余烬数据的主要特征之一。这也是Apollo client for GraphQL最受欢迎的特性之一。就这么简单:大多数复杂的前端应用程序都需要客户端缓存层来防止资源的过度获取。如果您面临这一要求,我建议您使用现有的解决方案之一。对于简单的用例,您还可以构建自己的服务。一个基本的实现可以如下所示:

    从'@ember/Service'导入服务;
    导出默认类StoreService扩展服务({
    postCache=新映射();
    装载站(id){
    设{postCache}=这个;
    if(postCache.has(id)){
    返回postCache.get(id);
    }
    let request=fetch(`/posts/${id}`);
    postCache.set(id,请求);
    返回请求;
    }
    });
    
    有几种技术可以在
    模型中加载多个资源。哪一个最适合您的需要,或者哪一个是可能的,这在很大程度上取决于您的应用程序。特别是所使用的后端API的功能,以及您的Ember应用程序是否使用或普通/ajax请求,会产生很大的不同

    最简单的情况是将Ember数据与REST API一起使用,REST API遵循并支持:

    从“@ember/routing/Route”导入路由;
    导出默认路由。扩展({
    模型({post_i