将功能从一个兄弟姐妹传递给另一个兄弟姐妹(2020 年的方式)

Passing function from one sibling to another (the 2020 way)

最近我开始使用 Angular,目前正在开发一个简单的仪表板。

我有一个组件“layout”,其中导入了所有其他组件,即“filter”和“table”。我的 table 组件看起来与 Angular 示例 (https://stackblitz.com/angular/xbgqqdajbax?file=src%2Fapp%2Ftable-filtering-example.html) 非常相似,但过滤器包含在组件中。我希望它是分开的,以便在其他地方也可以使用它。

这是我的过滤器组件:


@Component({
    selector: 'app-filter',
    templateUrl: './filter.component.html',
    styles: [],
})
export class FilterComponent implements OnInit {
    value = ''

    constructor() {}

    ngOnInit(): void {}
}

过滤器模板

    <mat-label>Filter</mat-label>
    <input
        matInput
        (keyup)="applyFilter($event)"
        placeholder="Ex. ium"
        #input
    />
</mat-form-field>

table 组件和 table 模板与 stackblitz 上的类似。

布局模板

<div>
    <app-nav></app-nav>

    <mat-grid-list cols="4" rowHeight="100">
        <mat-grid-tile
            [colspan]="4"
            [rowspan]="1"
            [ngStyle]="{ background: 'lightgreen' }"
        >
            <app-datepicker></app-datepicker>
        </mat-grid-tile>

        <mat-grid-tile
            [colspan]="4"
            [rowspan]="1"
            [ngStyle]="{ background: 'lightblue' }"
        >
            <app-filter></app-filter
        ></mat-grid-tile>

        <mat-grid-tile
            [colspan]="4"
            [rowspan]="7"
            [ngStyle]="{ background: 'lightpink' }"
        >
            <app-table></app-table
        ></mat-grid-tile>

        <mat-grid-tile
            [colspan]="4"
            [rowspan]="3"
            [ngStyle]="{ background: '#DDBDF1' }"
        >
            4</mat-grid-tile
        >
    </mat-grid-list>
</div>

布局组件


@Component({
    selector: 'app-layout',
    templateUrl: './layout.component.html',
    styles: [
        `
            app-table {
                width: 90%;
            }
        `,
    ],
})
export class LayoutComponent implements OnInit {
    constructor() {}

    ngOnInit(): void {}
}

我阅读了有关 rxjs、child > parent、parent > child 等的内容,但我找不到任何解释如何使用函数执行此操作的内容。所以我可以在技术上将字符串从一个组件传递到另一个组件,但它不适用于模板中的函数。

感谢任何帮助。

您可以将 Filter 组件用作任何其他组件的子组件,就像您在此处使用的侧面布局组件 ->

您可以在 filter.component.ts 中使用输出事件发射器 @Output Eventemitter 将输出字符串从过滤器组件传递到任何其他组件。

并在布局或任何其他组件中观察输出发射器 Html :

<app-filter (eventChange)="outputString($event)"></app-filter>

ts : outputString(event: string) { console.log('Output String',event) }

为了将事物分开,我建议采用以下方法:

在您的 filter.component.ts 中,当过滤器值更改时发出一个事件

@Output() onValueChanged = new EventEmitter<string>();

您在 filter.component.html 中触发了此事件。或者理想情况下,你也可以限制它并在你的过滤器组件中的某个地方触发它,例如文本在 100 毫秒后没有改变(以避免触发许多事件)

(keyup)="onValueChanged.emit(currentValue)"

在您的 layout 组件中,您可以监听事件并触发 table 过滤机制。

<app-filter (onValueChanged)="table.applyFilter($event)"></app-filter>
<app-table #table></app-table>

在您的 table 中,您必须实施 applyFilter 函数

您可以在过滤器组件模板中添加

<input type="text" (change)=changeFilter($event)>

然后在Filter组件里面添加

@Output() filterChanged = new EventEmitter();
changeFilter(changeEvent) { this.filterChanged.emit(changeEvent.target.value)}

在 Layout 元素中,您可以使用

访问输出
<app-filter (filterChanged)=setNewFilter($event)></app-filter>

并在布局组件中访问新的过滤器值,如

filter: string = '';
setNewFilter(newFilter: string) { this.filter = newFilter }

最后按预期将过滤器传递到 table 元素中:

<app-table [filter]="filter"></app-table>

可以通过输入在 app-Table 组件内部使用

@Input() filter = '';