【问题标题】:Multiple collections in Angular-in-memory-web-apiAngular-in-memory-web-api 中的多个集合
【发布时间】:2017-03-02 00:05:44
【问题描述】:

我们如何使用 Angular-in-memory-web-api 创建多个集合? 单一收藏不是问题。但我无法为多个集合实现它。

例如,我想在内存数据库中创建两个集合——国家和城市。任何想法,如何做到这一点?

【问题讨论】:

    标签: angular api in-memory-database


    【解决方案1】:

    只需返回一个包含两个数组的对象。在 Angular 的示例中,您会看到类似

    createDb() {
      let heroes = [ .. ]
      return { heroes }
    }
    

    如果您还不知道这一点,{ heroes } 只是写作{ heroes: heroes } 的简写。因此,如果您有两个集合,则只需将其添加为另一个属性

    createDb() {
      let heroes = [ .. ];
      let crises = [ .. ];
      return { heroes, crises };
      // or { heroes: heroes, crises: crises }
    }
    

    返回的属性名称将用于 URL 中的路径。所以你可以使用

    /api/heroes/1
    /api/crises/1
    

    【讨论】:

    • 这很好 - 但 heroes example 也会覆盖 genId(heroes: Hero[]): number { ... }。现在我尝试重载它以使用crises(即genId(crises: Crises[]): number { ... }),但到目前为止没有运气(“重复函数实现”)。你会怎么做? (在示例中,它返回最大 id + 1 以便能够添加新项目)
    • 终于找到了让它工作的方法,并将其发布在here 作为您答案的附加信息。
    【解决方案2】:

    Paul's answer 中描述的方法是正确的,但是我错过了一个我想补充的细节:你如何正确指定 genId,所以它适用于两个集合?

    答案是指用TypeScript(JavaScript 的超集)编写的“英雄”示例,特别是HTTP chapter。 在那里,通过实现模拟了一个表heroes

    export class InMemoryDataService implements InMemoryDbService {
      createDb() {
        const heroes = [
          { id: 11, name: 'Mr. Nice' },
          { id: 12, name: 'Narco' },
          // ...
          { id: 20, name: 'Tornado' }
        ];
        return {heroes};
      }
    
      // Overrides the genId method to ensure that a hero always has an id.
      // If the heroes array is empty,
      // the method below returns the initial number (11).
      // if the heroes array is not empty, the method below returns the highest
      // hero id + 1.
      genId(heroes: Hero[]): number {
        return heroes.length > 0 ? Math.max(...heroes.map(hero => hero.id)) + 1 : 11;
      }
    }
    

    现在,如果您添加 第二个集合crises,如他的回答所示,即:

    createDb() {
      let heroes = [ { ... }, ... ];
      let crises = [ { ... }, ... ];
      return { heroes, crises };
      // or { heroes: heroes, crises: crises }
    }
    

    您如何为这两个集合提供genId(假设它们的类型为HeroCrises)?重载,就像您在 C# 中所做的那样,在 TypeScript 中不起作用,它会引发错误(“重复函数实现”)。


    解决方案: 我发现,您可以使用 TypeScript's Generics 解决此问题,如下所示。将原来的genId 函数替换为以下通用版本:

    genId<T extends Hero | Crises>(myTable: T[]): number {
      return myTable.length > 0 ? Math.max(...myTable.map(t => t.id)) + 1 : 11;
    }
    

    这里重要的是&lt;T extends Hero | Crises&gt;部分:这意味着T类型可以是HeroCrises:所以如果传递的参数是Hero[]或@987654344类型,它将被调用@。

    有了这些知识,添加 3rd、4th、... 类很简单: 只需附加类即可。假设我们要添加类SuperHero,然后您只需通过| SuperHero 附加它,所以它看起来像:

    genId<T extends Hero | Crises | SuperHero>(myTable: T[]): number {
      return myTable.length > 0 ? Math.max(...myTable.map(t => t.id)) + 1 : 11;
    }
    

    注意:作为先决条件,所有类HeroCrisesSuperHero)都需要声明一个数字 id 属性。


    有用的链接:

    【讨论】:

    • @Matt,很高兴您提供了文档/相关文章的链接?
    【解决方案3】:

    除了这个讨论之外,我不得不使用 Partial,因为它一直说我在完成英雄之旅第 6 课时缺少一个 id。我使用消息服务查看代码在停止工作之前走了多远,所以您可以忽略 this.log 行,但您可以将它们添加到您自己的项目中以帮助调试。首先,我将 addHero 更新如下:

    addHero(hero: string): void { this.log(`In addHero of HeroesComponent, name is: ${hero}`);
    if (!hero)
    {
      this.log(`In if(!hero.name) of add hero: ${hero}`);
      return;
    }
    
    this.heroService.addHero({ name: hero } as Partial<Hero>)
      .subscribe(hero => {
        this.heroes.push(hero);
      });
    

    }

    然后我更新了 heros.service.ts 文件以使用部分 hero 并允许代码从 in-memory-data.service.ts 生成自己的 id:

    addHero(hero: Partial): Observable { this.log(`In addHero: heroeName is: ${hero.name}`); return this.http.post(this.heroesUrl, hero, this.httpOptions).pipe( tap((newHero: Hero) => this.log(`added hero with string id=${newHero.id}`)), catchError(this.handleError("Error in addHero"))); }

    据我所知,它现在按预期工作。可能还有更多代码需要更新,但这应该可以帮助任何出现以下错误消息的人:

    ERROR in src/app/heroes/heroes.component.ts:52:30 - error TS2352: Conversion of type '{ name: never; }' to type 'Hero' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Property 'id' is missing in type '{ name: never; }' but required in type 'Hero'.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-19
      • 1970-01-01
      • 1970-01-01
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-27
      相关资源
      最近更新 更多