简体   繁体   English

如何删除angularfire2中的链接引用?

[英]How to delete linked references in angularfire2?

I have three models City (have multiple Block s), Block (have multiple Area s) and Area (the one to many relation continues to other models, not showing here). 我有三个模型City(具有多个Block),Block(具有多个Area)和Area(与其他模型的一对多关系在这里没有显示)。

From the picture you can see I have flatten the data and using $key references. 从图片中您可以看到我已经整理数据并使用$key引用。

My question is what is the best way to store this data and how to delete all linked references? 我的问题是存储此数据的最佳方法是什么,以及如何删除所有链接的引用? Say when one City is deleted all the references of Block and all the Area linked with Block should be deleted. 假设删除一个城市时,应该删除Block的所有参考以及与Block链接的所有Area。

Below is the data structure 下面是数据结构

在此处输入图片说明

The code I am right now using to delete is, not upto Area deletion: 我现在用来删除的代码不是,而不是区域删除:

    deleteCity(city: City): void {
      this.af.database.list(`/cities/${city.$key}/blocks`, { preserveSnapshot: true })
                .subscribe(snapshots => {
                    snapshots.forEach(snapshot => {
                          this.af.database.object(`/blocks/${snapshot.key}`).remove();
                        });
              });
       this.af.database.list('/cities').remove(city.$key).then(
            () => this.appstore.dispatch({ type: DELETE_CITY, payload: city})
    );
  }

Please suggest about the data design and also deletion process. 请提出有关数据设计以及删除过程的建议。

The first thing you should probably do is wait until the blocks have been removed before removing the city: 您可能要做的第一件事是等到街区被删除后再删除城市:

import 'rxjs/add/operator/first';
import 'rxjs/add/operator/toPromise';

// Use the first operator to take the first emitted list and then
// complete the observable and use the toPromise operator to
// convert it into a promise for simpler chaining.

deleteCity(city: City): void {
  this.af.database
    .list(`/cities/${city.$key}/blocks`, { preserveSnapshot: true })
    .first()
    .toPromise()
    .then(snapshots => {
      snapshots.forEach(snapshot => {
        this.af.database.object(`/blocks/${snapshot.key}`).remove();
      });
    })
    .then(() => this.af.database.list('/cities').remove(city.$key))
    .then(() => this.appstore.dispatch({ type: DELETE_CITY, payload: city});
);

You should do something similar for areas, too. 您也应该对区域执行类似的操作。

Beyond that, any changes to the database structure the data depend upon how you want to access it. 除此之外,对数据库结构的任何更改都取决于数据的访问方式。

If you only need to access blocks in the context of a city and areas in the context of a block and never need to access arbitrary blocks or areas, you could include the city key in their paths: 如果您只需要在城市环境中访问街区,而在街区中访问区域而不需要访问任意街区,则可以在其路径中包括城市密钥:

/areas/$cityKey/$areaKey
/blocks/$cityKey/$blockKey

Removing all of the blocks and areas for a city, etc. is then trivial. 删除城市等的所有街区和区域就变得很简单。

Another option would be to use the cityKey child property that you have in each block. 另一个选择是使用每个块中具有的cityKey子属性。 You can grab those with a query like this: 您可以使用以下查询来获取这些内容:

this.af.database
  .list(`/blocks`, {
    preserveSnapshot: true,
    query: {
      orderByChild: 'cityKey',
      equalTo: '-KaXa...'
    }
  })

Similarly, if you add a cityId child to areas, you could query those in a similar manner. 同样,如果将cityId子级添加到区域中,则可以类似的方式查询它们。 That would at least avoid having to get all of the blocks for a city and all of the areas for each block; 这样至少可以避免必须获取一个城市的所有街区以及每个街区的所有区域。 you'd just get all of the blocks and areas using the city key. 您只需使用城市钥匙获取所有街区和区域。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM