我想从在路由器出口内呈现的子组件进行导航。我的父组件有一个路由器配置,我想手动导航某些事件。但是我不知道如何在没有输出的情况下将一些数据(用于导航)从子级传递到父级。因为这种结构是非工作的
<router-outlet (navigateTo)="navigateToMessagePart($event)"></router-outlet>
我怎样才能以正确的方式做到这一点?也许从孩子那里导航它?但是我如何从孩子那里获得父母的方法。非常感谢任何帮助!
<router-outlet></router-outlet>
不能用于从子组件发出事件。在两个组件之间进行通信的一种方法是使用公共服务。
创建服务
共享服务.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);
});
}
}
<router-outlet></router-outlet>
只是一个用于添加路由组件的占位符。不支持任何类型的绑定。
您可以创建自定义<router-outlet>
,以允许您执行此操作,或者更常见的是,使用共享服务在父组件和路由组件之间进行通信。
有关更多详细信息,请参阅 https://angular.io/docs/ts/latest/cookbook/component-communication.html
更新
现在有一个事件允许获取添加的组件
<router-outlet (activate)="componentAdded($event)" (deactivate)="componentRemoved($event)"></router-outlet>
它允许与componentAdded()
中的组件进行通信(调用 getter、setter 和方法)
不过,共享服务是首选方式。
给出的答案是正确和完整的。我只想为那些解决方案对他们不起作用的人补充一点,他们应该仅在父组件而不是子组件中将服务添加到提供程序,以确保您获得服务的单一实例,否则将创建两个服务实例。此回复的灵感来自上一个回复中@HeisenBerg的评论。
我与Antara Datta的回答相比略有改变。我创建了一个订阅者服务
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);
}
}
每当我需要两个组件来共享一些信息时,我都会在订阅它的构造函数中注入此服务:
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});
}
我无法理解为什么路由器不转发"@Outputs"。
我最终调度了准系统DOM事件
// dom node needs to be a reference to a DOM node in your component instance
// preferably the root
dom.dispatchEvent(
new CustomEvent('event', {
detail: payload, // <- your payload here
bubbles: true,
composed: true,
})
);
您可以像任何其他 DOM 事件一样在 DOM 树上的任何位置捕获它
注意:您需要从接收端的{ detail: payload }
中解压缩有效负载。