Angular 10,带有 EventEmitter 的路由器出口输出到 SideNav 内容中的父级
Angular 10,router-outlet output with EventEmitter to parent in SideNav Content
我有一个布局页面,it.I 中的 mat-sidenav-container 和 router-outlet 尝试调用该函数并通过 EventEmitter 从 router-outlet 页面向 LayoutPage 传递数据,但它不起作用。
我在这里发现了类似的问题:
@Output with EventEmitter from child to parent, view doesn't update in parent
如果将 router-outlet 标签替换为组件选择器标签(app-child)也是可行的,但是 router-outlet 标签对于 me.I 需要通过 router-outlet 导航网页 tag.How 那我可以吗?
layout.component.html
<mat-sidenav-container>
<mat-sidenav #sideNav opened="true" mode="side" class="sidebar" style="background-image: url('assets/images/test.png');">
<ul class="nav">
<li routerLinkActive="active" *ngFor="let menuItem of menuItems" class="test nav-item">
<a class="nav-link" [routerLink]="[menuItem.path]" [queryParams]="filter">
<i class="material-icons">{{menuItem.icon}}</i>
<p>{{menuItem.title}}</p>
</a>
</li>
</ul>
</mat-sidenav>
<mat-sidenav-content class="content">
<app-header></app-header>
<router-outlet (onDatePicked)='doSomething($event)' > </router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>
layout.component.ts
@Component({
selector: 'app-layout',
templateUrl: './layout.component.html',
styleUrls: ['./layout.component.css']
})
export class ChemoLayoutComponent implements OnInit {
filter:Filter
menuItems: any[];
constructor(private route: ActivatedRoute,private app: ApplicationRef) {
this.menuItems = [
{ path: '/chemo/child', title: 'aaa', icon: 'library_books' },
{ path: '/chemo/child1', title: 'bbb', icon:'build'},
{ path: '/chemo/child2', title: 'ccc', icon:'search' },
];
this.filter = new Filter();
}
ngOnInit(): void {
this.route.queryParams.subscribe((params) => {
this.filter.CHARTNO = params['CHARTNO'];
});
}
doSomething($event){ //<== It's not working
this.app.tick();
console.log("Test");
}
}
child.component.ts
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Output() onDatePicked: EventEmitter<any> = new EventEmitter<any>();
constructor() {
}
ngOnInit(): void {
this.onDatePicked.emit("hello");
}
}
<router-outlet (onDatePicked)='doSomething($event)' > </router-outlet>
这将不起作用,因为 onDatePicked
输出在 RouterOutlet
上不存在(参见 Angular doc)。
如果你想不受路由的限制从子组件到父组件进行通信,你需要实现一个服务。它可以看起来像这样:
子对parent.service.ts
@Injectable({
providedIn: 'root'
})
export class ChildToParentService {
onDatePicked$ = new Subject<any>();
constructor() { }
}
layout.component.ts
@Component({
selector: 'app-layout',
templateUrl: './layout.component.html',
styleUrls: ['./layout.component.css']
})
export class ChemoLayoutComponent implements OnDestroy {
onDatePickedSub: Subscription;
constructor(
private childToParentService: ChildToParentService
) {
this.onDatePickedSub = this.childToParentService.onDatePicked$.subscribe($event => {
this.doSomething($event);
});
}
ngOnDestroy(): void {
if (this.onDatePickedSub) {
this.onDatePickedSub.unsubscribe();
}
}
doSomething($event): void {
this.app.tick();
console.log("Test");
}
}
child.component.ts
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
constructor(
private childToParentService: ChildToParentService
) { }
ngOnInit(): void {
this.childToParentService.onDatePicked$.next('hello');
}
}
我有一个布局页面,it.I 中的 mat-sidenav-container 和 router-outlet 尝试调用该函数并通过 EventEmitter 从 router-outlet 页面向 LayoutPage 传递数据,但它不起作用。 我在这里发现了类似的问题: @Output with EventEmitter from child to parent, view doesn't update in parent
如果将 router-outlet 标签替换为组件选择器标签(app-child)也是可行的,但是 router-outlet 标签对于 me.I 需要通过 router-outlet 导航网页 tag.How 那我可以吗?
layout.component.html
<mat-sidenav-container>
<mat-sidenav #sideNav opened="true" mode="side" class="sidebar" style="background-image: url('assets/images/test.png');">
<ul class="nav">
<li routerLinkActive="active" *ngFor="let menuItem of menuItems" class="test nav-item">
<a class="nav-link" [routerLink]="[menuItem.path]" [queryParams]="filter">
<i class="material-icons">{{menuItem.icon}}</i>
<p>{{menuItem.title}}</p>
</a>
</li>
</ul>
</mat-sidenav>
<mat-sidenav-content class="content">
<app-header></app-header>
<router-outlet (onDatePicked)='doSomething($event)' > </router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>
layout.component.ts
@Component({
selector: 'app-layout',
templateUrl: './layout.component.html',
styleUrls: ['./layout.component.css']
})
export class ChemoLayoutComponent implements OnInit {
filter:Filter
menuItems: any[];
constructor(private route: ActivatedRoute,private app: ApplicationRef) {
this.menuItems = [
{ path: '/chemo/child', title: 'aaa', icon: 'library_books' },
{ path: '/chemo/child1', title: 'bbb', icon:'build'},
{ path: '/chemo/child2', title: 'ccc', icon:'search' },
];
this.filter = new Filter();
}
ngOnInit(): void {
this.route.queryParams.subscribe((params) => {
this.filter.CHARTNO = params['CHARTNO'];
});
}
doSomething($event){ //<== It's not working
this.app.tick();
console.log("Test");
}
}
child.component.ts
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Output() onDatePicked: EventEmitter<any> = new EventEmitter<any>();
constructor() {
}
ngOnInit(): void {
this.onDatePicked.emit("hello");
}
}
<router-outlet (onDatePicked)='doSomething($event)' > </router-outlet>
这将不起作用,因为 onDatePicked
输出在 RouterOutlet
上不存在(参见 Angular doc)。
如果你想不受路由的限制从子组件到父组件进行通信,你需要实现一个服务。它可以看起来像这样:
子对parent.service.ts
@Injectable({
providedIn: 'root'
})
export class ChildToParentService {
onDatePicked$ = new Subject<any>();
constructor() { }
}
layout.component.ts
@Component({
selector: 'app-layout',
templateUrl: './layout.component.html',
styleUrls: ['./layout.component.css']
})
export class ChemoLayoutComponent implements OnDestroy {
onDatePickedSub: Subscription;
constructor(
private childToParentService: ChildToParentService
) {
this.onDatePickedSub = this.childToParentService.onDatePicked$.subscribe($event => {
this.doSomething($event);
});
}
ngOnDestroy(): void {
if (this.onDatePickedSub) {
this.onDatePickedSub.unsubscribe();
}
}
doSomething($event): void {
this.app.tick();
console.log("Test");
}
}
child.component.ts
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
constructor(
private childToParentService: ChildToParentService
) { }
ngOnInit(): void {
this.childToParentService.onDatePicked$.next('hello');
}
}