Несколько коллекций в Angular-in-memory-web-api
Как создать несколько коллекций, используя Angular-in-memory-web-api? Не проблема с одной коллекцией. Но я не могу реализовать это для нескольких коллекций.
Например, я хочу создать, скажем, две коллекции в памяти БД - Страна и Города. Есть идеи, как это сделать?
Ответы
Ответ 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
Ответ 2
Подход, описанный в ответе Пола, верен, однако я упустил одну деталь, которую я хотел бы добавить: как правильно указать genId
, чтобы он работал для обеих коллекций?
Ответ относится к примеру "Герои", написанному на TypeScript (расширенный набор JavaScript), в частности к главе HTTP. Там таблица 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;
}
}
Теперь, если вы добавите 2-й сборник crises
как показано в его ответе, то есть:
createDb() {
let heroes = [ { ... }, ... ];
let crises = [ { ... }, ... ];
return { heroes, crises };
// or { heroes: heroes, crises: crises }
}
как вы предоставляете genId
для обеих коллекций (при условии, что они относятся к типу Hero
и Crises
)? Перегрузка, как вы это делаете в C#
, не работает в TypeScript, она выдает ошибку ("Реализация дублирующейся функции").
Решение: Я обнаружил, что вы можете решить эту проблему с помощью TypeScript Generics следующим образом. Замените genId
функцию genId
следующей универсальной версией:
genId<T extends Hero | Crises>(myTable: T[]): number {
return myTable.length > 0 ? Math.max(...myTable.map(t => t.id)) + 1 : 11;
}
Что здесь важно, так это часть <T extends Hero | Crises>
<T extends Hero | Crises>
: это означает, что тип T
может быть либо Hero
либо Crises
: поэтому он будет вызываться, если переданный параметр имеет тип Hero[]
или Crises[]
.
С этим знанием добавить 3-й, 4-й,... класс просто: просто добавьте класс. Скажем, мы хотим добавить класс SuperHero
, тогда вы просто добавляете его через | SuperHero
| SuperHero
, так это будет выглядеть так:
genId<T extends Hero | Crises | SuperHero>(myTable: T[]): number {
return myTable.length > 0 ? Math.max(...myTable.map(t => t.id)) + 1 : 11;
}
Примечание. В качестве предварительного условия для всех классов (Hero
, Crises
и SuperHero
) необходимо объявить числовое свойство id
.
Полезные ссылки: