首页 > 解决方案 > 如何在 Ember.js 中迭代保存子记录?

问题描述

我想使用 Ember Data 将父记录和多个子记录保存到外部 REST API。我遇到的问题是我不确定异步处理这个问题的最佳方法是什么。

我的第一次尝试看起来像这样:

let parent = this.store.createRecord('parent');
parent.set('name', 'Bob');
parent.set('children', []);
parent.save().then(()=>{
  for (i=0;i<8;i++) {
    let child = this.store.createRecord('child');
    child.set('name', 'Child' + i);
    child.set('parent', parent);
    child.save().then(()=>{
      parent.get('children').pushObject(child);
      if (i == 7) {parent.save()}
    }
  }
})

这成功创建了父级和所有子级,但未能将所有子级的 id 保存在父级记录中。并非所有 child.save() 承诺都在调用 parent.save() 时解决。

我知道 RSVP 是一个可用于解决此问题的库,但我找不到任何在上下文中对我正在尝试做的事情有意义的使用示例。

任何人都可以概述我如何重做这个以确保在尝试拯救父母之前已经拯救了所有孩子吗?

标签: ember.jsasync-awaitember-datarsvp.js

解决方案


奥拉@Bean,谢谢你的问题

正如@jelhan 在他的评论中所问的那样,这个问题的答案实际上取决于您的 API 可以支持什么,我将通过一些假设和概括来回答您的问题,但希望它会有用!

首先让我们明确一点,我将为 Parent 和 Child 定义模型,以便我们知道它是如何工作的。

// app/models/parent.js
import DS from 'ember-data';
const { Model, attr, hasMany } = DS;

export default Model.extend({
  name: attr(),
  children: hasMany('child'),
});
// app/models/child.js
import DS from 'ember-data';
const { Model, attr, belongsTo } = DS;

export default Model.extend({
  name: attr(),
  parent: belongsTo('parent'),
});

现在我们有了模型,我将像您的示例一样设置一个父级和 8 个子级,但在我的示例中,为了清楚起见,我将单独保存:

// create 1 parent
let parent = this.store.createRecord('parent', {
  name: 'Bob'
});

// create 8 children
let children = [];

for (i=0;i<8;i++) {
  let child = this.store.createRecord('child', {
    name: 'Child' + i
  });

  children.push(child);
}

因此,现在您将在商店中有 1 个父级和 8 个子级,但没有网络请求,因为我们没有保存任何内容。

您现在有 2 个选项(取决于您的后端支持的内容)。您可以:

  • 首先保存父级
  • 在每个孩子上设置父母
  • 拯救每个孩子

或者您可以:

  • 拯救每个孩子
  • 将 parent 的 children 数组设置为子模型的集合
  • 保存父母

我现在将在一个示例中介绍这两个选项。我正在使用 async-await 使其更易于阅读,因此请确保您正确使用它

// Save parent first
await parent.save();

let promises = children.map((child) => {
  child.set('parent', parent);
  return child.save();
})

await Promise.all(promises);
// Save children first
let promises = children.map((child) => {
  return child.save();
})

await Promise.all(promises);

parent.set('children', children);

await parent.save();

由于 ember-data 的工作方式,它应该自动为您关联反向关系如果您想了解更多信息,可以查看官方 Ember 文档https://guides.emberjs.com/release/上的文档模型/关系/#toc_explicit-inverses


推荐阅读