Angular 5公式Tutorialの作例を改善する
Angularの公式Tutorialは、全体をとおしてひとつの作例「Angular Example - Tour of Heroes: Part 6 」をつくります。この解説を下じきに、もっと細かくコードの動きが確かめられるように、説明の仕方やサンプルも改めて「Angular 5入門」を書きました。そのとき、公式の作例にいくつか気づいて直した点があります。それらをご紹介しましょう。
要らないコードを除く
「Routing」の「Remove dead code (optional)」は、書き直しの結果要らなくなったコードを除いています。これに加えてもうひとつ削った方がよいのは、HeroDetailComponentクラスのデコレータ関数Input()
です。
import { Component, OnInit, Input } from '@angular/core';
export class HeroDetailComponent implements OnInit {
@Input() hero: Hero;
}
コンポーネントの詳細情報(hero-detail.component)をリスト表示(heroes.component)から分け、選択されたデータをサービスから得るようにしたからです。親だったリスト表示のコンポーネントから参照を得るためにプロパティ(hero)に添えていたデコレータ関数Input()は意味がなくなります。
import { Component, OnInit} from '@angular/core';
export class HeroDetailComponent implements OnInit {
hero: Hero;
}
公式Tutorialにもこの修正が加えられそうです(「refactor(aio): refining code of tutorial 7 routing」)。
リストを空にするとデータが加えられない
まず、リスト表示の画面ですべての項目を削除します(図001)。
図001■リスト項目がなくなった
つぎに、新たな項目をテキストフィールドに入力して、[add]ボタンを押します(図002)。
図002■新たな項目を入力する
すると、番号もテキストも空の項目が加えられます(図003)。ブラウザのコンソールを確かめると、つぎのようなエラーが示されました。
body: {error: "Collection 'heroes' id type is non-numeric or unknown. Can only generate numeric ids."}
図003■番号とテキストが空の項目
データの配列が空になって、プロパティidをもつオブジェクトがなくなると、新たな番号はつくれず、データも加えられないようです。
HttpClient.put()
メソッドを使えば、データにid番号を定めて追加できます。リストが空のときは、つぎのようにidは初期値にしてHttpClient.put()
メソッドでデータを送ればよいでしょう。
export class HeroService {
// addHero(hero: Hero): Observable<Hero> {
addHero(hero: Hero, numHeros: number): Observable<Hero> {
let heroOvserbable;
// return this.http.post<Hero>(this.herosUrl, hero, httpOptions)
if (numHeros === 0) {
hero.id = 11;
heroOvserbable = this.http.put(this.herosUrl, hero, httpOptions)
} else {
heroOvserbable = this.http.post<Hero>(this.herosUrl, hero, httpOptions);
}
return heroOvserbable
}
}
ただし、サービスのクラス(HeroService)はデータの配列を知りません。ですから、リスト表示クラス(HerosComponent)がデータ追加(add()メソッド)のためにサービス(HeroService)のメソッド(addHero())を呼び出すとき、第2引数としてデータ(heros)の長さ(Array.length
プロパティ)を渡します。
export class HerosComponent implements OnInit {
add(name: string): void {
// this.heroService.addHero({name} as Hero)
this.heroService.addHero({name} as Hero, this.heros.length)
}
}
これで、リストを空にしても新たな項目が加えられます。これらの手直しをした作例は「Angular Example - Tour of Heroes: Part 6 revised」に掲げました。
Angular in-memory-web-apiモジュールのメソッドをオーバーライドする
リストを空にすると新たな項目がつくれないのは、Angular in-memory-web-api moduleの仕様にもとづくようです。デフォルトのid番号を返すBackendService.genIdDefault()
メソッドは、BackendService.isCollectionIdNumeric()
メソッドで、リストのデータがあり、さらに数値のidプロパティをもつかどうか確かめます。そうでなければ、デフォルトのid番号はできず、エラーになるのです。
データにid番号を振るのはBackendService.genId()
メソッドです。このメソッドは、InMemoryDataServiceクラス(in-memory-data.service)でオーバーライドできます(「Tutorial example has a problem to enter new item into an empty list」参照)。すると、前項のようにサービス(HeroService)やリスト表示(HerosComponent)のクラスは書き替えずに済むのです。
InMemoryDataServiceクラスに定めてオーバーライドするつぎのgenId()メソッドは、データがあればid番号の最大値 + 1、なければ初期値を返します。この作例は"Angular Example - Tour of Heroes: Part 6"に掲げられています。
export class InMemoryDataService implements InMemoryDbService {
genId(heroines: Heroine[]): number {
return heroines.length > 0 ? Math.max(...heroines.map(heroine => heroine.id)) + 1 : 11;
}
}
おまけ
細かいところで、もうひとつつけ加えておきます。サービスのクラス(HeroService)の検索メソッド(searchHeroes())で、URLを直書きしているところです。もとのパスはプロパティ(heroesUrl)に定めてあります。後あとの修正も考えるなら、プロパティを用いるべきでしょう。
export class HeroService {
searchHeroes(term: string): Observable<Hero[]> {
const url = `${this.heroesUrl}/?name=${term}`;
// return this.http.get<Hero[]>(`api/heroes/?name=${term}`)
return this.http.get<Hero[]>(url)
}
}
Author And Source
この問題について(Angular 5公式Tutorialの作例を改善する), 我々は、より多くの情報をここで見つけました https://qiita.com/FumioNonaka/items/084622b7111280046e58著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .