在 Angular 个组件中发出和捕获事件
Emit and Catch event in Angular components
我创建了以下 Angular 7 个手风琴组件 SlackBlitz Example:
export class AccordionComponent {
@ContentChildren(PanelComponent) panels: QueryList<PanelComponent>;
ngAfterContentInit() {
this.panels.forEach((panel) => {panel.active = false;});
}
onReset(panel: PanelComponent) {
this.panels.toArray().forEach(panel => panel.active = false);
}
}
PanelComponent 如下:
export class PanelComponent {
@Input() active: boolean;
@Input() title: string;
@Output() reset: EventEmitter<PanelComponent> = new EventEmitter();
toggle() {
this.active = !this.active;
if (this.active)
this.reset.emit(this);
}
}
当我打开一个面板时,我需要关闭所有其他面板...
我的解决方案是:
设置active = true
时在toggle函数中触发事件;
我想我需要在活动中通过小组本身吗?
在 Accordion 组件中捕获该事件。
并在面板通过事件后关闭所有其他面板。
这可能吗?怎么样?
您可以在 accordion.component
和 subscribe
中捕获输出事件。
面板组件
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'panel',
templateUrl: './panel.component.html'
})
export class PanelComponent {
@Input() active: boolean;
@Input() title: string;
@Output() activate = new EventEmitter();
toggle() {
this.active = !this.active;
if (this.active) {
this.activate.emit();
}
}
}
手风琴组件
import { Component, ContentChildren, QueryList } from '@angular/core';
import { Subject } from 'rxjs'
import { takeUntil } from 'rxjs/operators'
import { PanelComponent } from './panel.component';
@Component({
selector: 'accordion',
templateUrl: './accordion.component.html'
})
export class AccordionComponent {
@ContentChildren(PanelComponent) panels: QueryList<PanelComponent>;
destroy$ = new Subject<boolean>();
ngAfterContentInit() {
this.panels.forEach((panel) => {
panel.active = false;
panel.activate.pipe(
takeUntil(this.destroy$)
).subscribe(() => {
this.closeAllButPanel(panel);
})
});
}
ngOnDestroy() {
this.destroy$.next(true);
this.destroy$.unsubscribe();
}
closeAllButPanel(panelToIgnore: PanelComponent) {
this.panels.filter(p => p!==panelToIgnore).forEach(panel => panel.active = false);
}
}
我创建了以下 Angular 7 个手风琴组件 SlackBlitz Example:
export class AccordionComponent {
@ContentChildren(PanelComponent) panels: QueryList<PanelComponent>;
ngAfterContentInit() {
this.panels.forEach((panel) => {panel.active = false;});
}
onReset(panel: PanelComponent) {
this.panels.toArray().forEach(panel => panel.active = false);
}
}
PanelComponent 如下:
export class PanelComponent {
@Input() active: boolean;
@Input() title: string;
@Output() reset: EventEmitter<PanelComponent> = new EventEmitter();
toggle() {
this.active = !this.active;
if (this.active)
this.reset.emit(this);
}
}
当我打开一个面板时,我需要关闭所有其他面板...
我的解决方案是:
设置
active = true
时在toggle函数中触发事件; 我想我需要在活动中通过小组本身吗?在 Accordion 组件中捕获该事件。 并在面板通过事件后关闭所有其他面板。
这可能吗?怎么样?
您可以在 accordion.component
和 subscribe
中捕获输出事件。
面板组件
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'panel',
templateUrl: './panel.component.html'
})
export class PanelComponent {
@Input() active: boolean;
@Input() title: string;
@Output() activate = new EventEmitter();
toggle() {
this.active = !this.active;
if (this.active) {
this.activate.emit();
}
}
}
手风琴组件
import { Component, ContentChildren, QueryList } from '@angular/core';
import { Subject } from 'rxjs'
import { takeUntil } from 'rxjs/operators'
import { PanelComponent } from './panel.component';
@Component({
selector: 'accordion',
templateUrl: './accordion.component.html'
})
export class AccordionComponent {
@ContentChildren(PanelComponent) panels: QueryList<PanelComponent>;
destroy$ = new Subject<boolean>();
ngAfterContentInit() {
this.panels.forEach((panel) => {
panel.active = false;
panel.activate.pipe(
takeUntil(this.destroy$)
).subscribe(() => {
this.closeAllButPanel(panel);
})
});
}
ngOnDestroy() {
this.destroy$.next(true);
this.destroy$.unsubscribe();
}
closeAllButPanel(panelToIgnore: PanelComponent) {
this.panels.filter(p => p!==panelToIgnore).forEach(panel => panel.active = false);
}
}