[解決済み] Angular2:コンポーネントをレンダリングする前にデータをロードする方法は?
質問
コンポーネントがレンダリングされる前に、APIからイベントをロードしようとしています。現在、私はコンポーネントのngOnInit関数から呼び出される私のAPIサービスを使用しています。
私の
EventRegister
コンポーネントを使用します。
import {Component, OnInit, ElementRef} from "angular2/core";
import {ApiService} from "../../services/api.service";
import {EventModel} from '../../models/EventModel';
import {Router, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, RouteConfig, RouteParams, RouterLink} from 'angular2/router';
import {FORM_PROVIDERS, FORM_DIRECTIVES, Control} from 'angular2/common';
@Component({
selector: "register",
templateUrl: "/events/register"
// provider array is added in parent component
})
export class EventRegister implements OnInit {
eventId: string;
ev: EventModel;
constructor(private _apiService: ApiService,
params: RouteParams) {
this.eventId = params.get('id');
}
fetchEvent(): void {
this._apiService.get.event(this.eventId).then(event => {
this.ev = event;
console.log(event); // Has a value
console.log(this.ev); // Has a value
});
}
ngOnInit() {
this.fetchEvent();
console.log(this.ev); // Has NO value
}
}
私の
EventRegister
テンプレート
<register>
Hi this sentence is always visible, even if `ev property` is not loaded yet
<div *ngIf="ev">
I should be visible as soon the `ev property` is loaded. Currently I am never shown.
<span>{{event.id }}</span>
</div>
</register>
私のAPIサービス
import "rxjs/Rx"
import {Http} from "angular2/http";
import {Injectable} from "angular2/core";
import {EventModel} from '../models/EventModel';
@Injectable()
export class ApiService {
constructor(private http: Http) { }
get = {
event: (eventId: string): Promise<EventModel> => {
return this.http.get("api/events/" + eventId).map(response => {
return response.json(); // Has a value
}).toPromise();
}
}
}
コンポーネントは、API 呼び出しの前に
ngOnInit
関数はデータの取得を終了します。そのため、ビューテンプレートにイベントIDが表示されることはありません。ということは、これはASYNCの問題のようです。私は
ev
(
EventRegister
コンポーネント) の後に何らかの作業をするために
ev
プロパティが設定されました。悲しいかな、これでは
div
でマークされた
*ngIf="ev"
が設定されると、そのプロパティは
質問です。 私は良い方法を使っているのでしょうか?そうでない場合、コンポーネントがレンダリングを開始する前にデータをロードする最良の方法は何でしょうか?
注意
は
ngOnInit
のアプローチは、この
angular2 チュートリアル
.
EDIT
考えられる解決策は2つ。1つ目は
fetchEvent
でAPIサービスを使用するだけです。
ngOnInit
関数を使用します。
ngOnInit() {
this._apiService.get.event(this.eventId).then(event => this.ev = event);
}
第二の解決策 与えられた答えのように。
fetchEvent(): Promise<EventModel> {
return this._apiService.get.event(this.eventId);
}
ngOnInit() {
this.fetchEvent().then(event => this.ev = event);
}
解決方法は?
更新
-
ルータを使用する場合は、ライフサイクルフックやリゾルバを使用して、データが到着するまでナビゲーションを遅らせることができます。 https://angular.io/guide/router#milestone-5-route-guards
-
ルートコンポーネントの初期レンダリングの前にデータをロードする場合
APP_INITIALIZER
は使用できます バックエンドからレンダリングされたパラメータをangular2 bootstrapのメソッドに渡す方法
オリジナル
いつ
console.log(this.ev)
の後に実行されます。
this.fetchEvent();
を意味するものではありません。
fetchEvent()
の呼び出しが完了したことを意味し、これはスケジュールされていることを意味するだけです。これは単にスケジュールされていることを意味します。
console.log(this.ev)
が実行された時点では、サーバーへの呼び出しも行われておらず、もちろんまだ値も返されていない。
変更
fetchEvent()
を返すようにします。
Promise
fetchEvent(){
return this._apiService.get.event(this.eventId).then(event => {
this.ev = event;
console.log(event); // Has a value
console.log(this.ev); // Has a value
});
}
変更
ngOnInit()
を待つようにします。
Promise
を完了させる
ngOnInit() {
this.fetchEvent().then(() =>
console.log(this.ev)); // Now has value;
}
これでは、あなたのユースケースのために、実はあまり買えません。
私の提案です。テンプレート全体を
<div *ngIf="isDataAvailable"> (template content) </div>
と
ngOnInit()
isDataAvailable:boolean = false;
ngOnInit() {
this.fetchEvent().then(() =>
this.isDataAvailable = true); // Now has value;
}
関連
-
[解決済み】Typescriptで、! (エクスクラメーションマーク/バン)演算子でメンバを再参照するのは?
-
[解決済み] Jest で typescript を使用して identity-obj-proxy を使用すると未定義が返される
-
[解決済み] グローバル定数の定義
-
[解決済み] TypeScriptで、「extends keyof」と「in keyof」はどういう意味ですか?
-
[解決済み] なぜTypescriptではinferキーワードが必要なのでしょうか?
-
[解決済み] コンポーネントテンプレートで要素を選択するには?
-
[解決済み] モジュール 'module-name' の宣言ファイルが見つかりませんでした。'/path/to/module-name.js' は暗黙のうちに 'any' 型を持っています。
-
[解決済み] TypeScriptの "*.d.ts "について
-
[解決済み] ジェネリックスを使用したTypescriptのarrow関数の構文はどのようになっていますか?
-
[解決済み] TypeScriptのクラス型チェック
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Typescript: スプレッド型はオブジェクト型からしか作成できない
-
[解決済み] TSLintの "文字列リテラルによるオブジェクトアクセス "を回避するためのコードの書き換え方法
-
[解決済み] Jestで関数をモックする方法
-
[解決済み] TypeScriptのInterface Function Property。何が違うの?
-
[解決済み] Typescript オブジェクトのインデックス付きメンバの型を強制する?
-
[解決済み] チェックした後に○○の表現が変わっている
-
[解決済み] noImplicitAnyフラグを有効にしてtypescriptをコンパイルすると、"Index signature of object type implicitly has an 'any' type "というエラーが発生しますが、どうすれば防ぐことができますか?
-
[解決済み] types/* を `dependencies` と `devDependencies` のどちらに入れるかは、どのように決めたらよいですか?
-
[解決済み】Visual Studio Codeで.js.mapファイルを非表示にする方法
-
[解決済み】TypescriptのArray<Type> VS Type[]について