ルーターアウトレット内でレンダリングする子コンポーネントからナビゲーションを作成したい。私の親コンポーネントにはルーター設定があり、何らかのイベントが発生した場合に手動でナビゲートしたいと考えています。しかし、出力せずに(ナビゲーション用の)データを子から親に渡す方法はわかりません。この構造は機能しないため
<router-outlet (navigateTo)="navigateToMessagePart($event)"></router-outlet>
どうすれば正しい方法でそれを行うことができますか?たぶん子供からそれをナビゲートしますか?しかし、子から親メソッドを取得する方法。助けてくれてありがとう!
<router-outlet></router-outlet>
は、ルーティングされたコンポーネントを追加するための単なるプレースホルダーです。あらゆる種類のバインディングはサポートされていません。
カスタム<router-outlet>
を作成して、それを可能にするか、より一般的に、共有サービスを使用して親コンポーネントとルーティングされたコンポーネント間で通信することができます。
詳細については、 https://angular.io/docs/ts/latest/cookbook/component-communication.html を参照してください
update
追加されたコンポーネントを取得できるイベントがあります
<router-outlet (activate)="componentAdded($event)" (deactivate)="componentRemoved($event)"></router-outlet>
componentAdded()
のコンポーネントと通信(ゲッター、セッター、およびメソッドを呼び出す)できるようにします
ただし、共有サービスが好ましい方法です。
<router-outlet></router-outlet>
を使用して、子コンポーネントからイベントを発行することはできません。 2つのコンポーネント間で通信する1つの方法は、共通のサービスを使用することです。
サービスを作成する
shared-service.ts
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class SharedService {
// Observable string sources
private emitChangeSource = new Subject<any>();
// Observable string streams
changeEmitted$ = this.emitChangeSource.asObservable();
// Service message commands
emitChange(change: any) {
this.emitChangeSource.next(change);
}
}
次に、上記のサービスのインスタンスを、親コンポーネントと子コンポーネントの両方のコンストラクターに注入します。
子コンポーネントは、onClick()メソッドが呼び出されるたびに変更を発行します
child.component.ts
import { Component} from '@angular/core';
@Component({
templateUrl: 'child.html',
styleUrls: ['child.scss']
})
export class ChildComponent {
constructor(
private _sharedService: SharedService
) { }
onClick(){
this._sharedService.emitChange('Data from child');
}
}
親コンポーネントはその変更を受け取るものとします。そのためには、親のコンストラクター内でサブスクリプションをキャプチャします。
parent.component.ts
import { Component} from '@angular/core';
@Component({
templateUrl: 'parent.html',
styleUrls: ['parent.scss']
})
export class ParentComponent {
constructor(
private _sharedService: SharedService
) {
_sharedService.changeEmitted$.subscribe(
text => {
console.log(text);
});
}
}
お役に立てれば :)
上記の答えは正確かつ完全です。ソリューションがうまくいかなかった人のために、サービスをシングルコンポーネントを取得するために、子ではなく親コンポーネントのみのプロバイダーにサービスを追加する必要があることを追加します。そうしないと、2つのサービスインスタンスが作成した。この応答は、前の応答の@HeisenBergのコメントに触発されています。
アンタラダッタの答えから少し変更しました。サブスクライバーサービスを作成しました
import {Injectable} from '@angular/core';
import {Subject} from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class Subscriber<T>
{
protected observable = new Subject<T>();
public next(item: T)
{
this.observable.next(item);
}
public subscribe(callback: (item:T)=>void) {
this.observable.subscribe(callback);
}
}
情報を共有するために2つのコンポーネントが必要になるたびに、サブスクライブするコンストラクターにこのサービスを注入します。
constructor(protected layoutOptions: Subscriber<Partial<LayoutOptions>>)
{
layoutOptions.subscribe(options => this.options = Object.assign({}, this.options, options));
}
そしてそれを更新するもの
constructor(protected router: Router, protected apiService: ApiService, protected layoutOptions: Subscriber<Partial<LayoutOptions>>)
{
this.layoutOptions.next({showNavBar: false});
}