2017-10-09 7 views
1

ルート用にラップする別のコンポーネントで使用するコンポーネントがあります。このコンポーネントは、バック親ルートへのナビゲーションをトリガー出力イベントがあります。ルータで使用されているコンポーネントの出力イベントで約束を解決できません

@Component({ 
    selector: 'hello', 
    template: ` 
    <ng-content></ng-content> 
    <button (click)="back($event)">Back</button> 
    ` 
}) 
export class HelloComponent { 
    @Output() helloBack = new EventEmitter(); 

    constructor(private router: Router, 
    private route: ActivatedRoute) { 
    } 

    back($event) { 
    this.router.navigate(['./'], { relativeTo: this.route.parent }) 
     .then(() => { 
     this.helloBack.emit($event); 
     }); 
    } 
} 

次に、私がルートで使用するラッパーコンポーネントを作成します。

@Component({ 
    template: ` 
    <hello (helloBack)="onBack()"> 
    <h1>Hello World!</h1> 
    </hello> 
    ` 
}) 
export class HelloRouteComponent { 
    onBack() { 
    console.log('back!!!'); 
    } 
} 

最後に、私はルーティングでこれを読み込みますモジュール:

RouterModule.forRoot([ 
    { 
    path: 'hello', 
    component: HelloRouteComponent 
    } 
]) 

私はHelloRouteComponent負荷罰金/helloルートに行きます。戻るボタンをクリックすると、親ルートに移動します。しかし、コンソールに正常にナビゲートした後はコンソールに何も記録されません。

なぜ約束が解決されないのですか?これが機能するには何が欠けていますか?

デモ:https://stackblitz.com/edit/angular-rewax8?file=app%2Fapp.component.ts

答えて

1

私は、これは時間router.navigate()によって解決され、かつhelloBack.emit()が呼び出されるので、HelloComponentがすでに取り外されているので、結合<hello (helloBack)="onBack()">はもう存在しないと考えています。

Subject<T>フィールド(@Outputイベント/ EventEmitterの自然な置換え)を宣言する共有サービスを使用することができます。代わりにその主題を使用してください。それは理にかなっていますか?


サービスは、次のように見ることができます:

@Injectable() 
export class HelloContextService { 

    private _helloBackSubject = new Subject<any>(); 
    $helloBack: Observable<any>; 

    constructor() { 
     this.$helloBack = this._helloBackSubject.asObservable(); 
    } 

    emitHelloBack(payload: any): void { 
     this._helloBackSubject.next(payload); 
    } 
} 

あなたのコンポーネントの両方に注入する必要があります。 HelloComponentthis.emitHelloBack($event)を呼び出すことができ、もう1つのコンポーネントは観測可能な$helloBackに登録することができます。

HelloComponent

export class HelloComponent { 

    constructor(private router: Router, 
     private route: ActivatedRoute, 
     private helloContextService: HelloContextService) { 
    } 

    back($event) { 
     this.router.navigate(['./'], { relativeTo: this.route.parent }) 
      .then(() => { 
       this.helloContextService.emitHelloBack($event); 
      }); 
    } 
} 

他の成分:アプリケーションで

export class HelloRouteComponent { 
    constructor(private helloContextService: HelloContextService) { 
     this.helloContextService 
      .$helloBack 
      .subscribe(payload => { 
       // ... 
      }); 
    } 
} 
+0

迅速な対応をありがとう。このサービスがどのように機能するかを実証できますか? – elclanrs

+0

コードを見てください。 :) –

+0

私は参照してください...これは私のユースケースのために、ルートコンポーネントが私のコンポーネントを消費するユーザーによって作成され、私はそれ以上のコントロールを持っていないので、私は使用する必要はありませんサービスを挿入するなどの操作を行います。 – elclanrs

0

あなたは@Output型の変数を定義することにより、イベント・エミッターを露出し、あなたは子供でcompoenentことをキャッチされています。だからすべてがよさそうだ。

this.router.navigateが呼び出されていない可能性があります。onBack(event: EditEvent)呼び出された関数にパラメータを渡していません。

@Component({ 
    selector: 'hello', 
    template: ` 
    <ng-content></ng-content> 
    <button (click)="back($event)">Back</button> 
    ` 
}) 
export class HelloComponent { 
    @Output() helloBack = new EventEmitter(); 

    constructor(private router: Router, 
    private route: ActivatedRoute) { 
    } 

    back($event) { 
    this.helloBack.emit({status: 'gone back'}); 
    this.router.navigate(['./'], { relativeTo: this.route.parent }) 
     .then(() => { 
     this.helloBack.emit($event); 

     }); 
    } 
} 

私はデバッグの少しはあなたの問題を解決すると思いますonBack方法

@Component({ 
    template: ` 
    <hello (helloBack)="onBack()"> 
    <h1>Hello World!</h1> 
    </hello> 
    ` 
}) 
export class HelloRouteComponent { 

    onBack(event: EditEvent) { 
    console.log('back!!!'); 
    } 
} 
Finally, I load this in the routing module: 

RouterModule.forRoot([ 
    { 
    path: 'hello', 
    component: HelloRouteComponent 
    } 
]) 

にパラメータを追加します。

関連する問題