【问题标题】:How can I execute multiple functions on click(or on change) in sibling components?如何在同级组件中单击(或更改)时执行多个功能?
【发布时间】:2020-03-07 09:48:03
【问题描述】:

我是 Angular 的新手,我正在开发一个基本的应用程序。我有几个兄弟组件,其中一个是按钮。通过单击按钮,我必须触发其他组件中的几个功能。 (按钮单击会用数据填充数组,所以当数组发生变化时,可能会触发函数。)如何做到这一点?

我尝试了:@Input-@Output、EventEmmiters、Services、Observables 和 Subscription,@Viewchild 并没有成功...数据在组件之间传输,但没有调用任何函数。那么还有其他想法吗?(或者我尝试过的例子,也许我做错了什么)

服务:

import { Injectable, Input } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class VisualService {

  public dataArray = [];

  private dataSource = new BehaviorSubject(this.dataArray);
  currentArray = this.dataSource.asObservable();

  constructor() { }

  updateData(array) {
    this.dataSource.next(array);
    this.dataArray = array;
    console.log(this.dataArray);
  }
}

我想触发函数的组件:

import { Component, OnInit, Input, ViewChild } from '@angular/core';
import { DialogComponent } from '../dialog/dialog.component';
import { MatDialog } from '@angular/material/dialog';
import { MatTable } from '@angular/material/table';
import { VisualService } from '../services/visual.service';


@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css']
})

export class TableComponent implements OnInit {

  @ViewChild('dataTable', { read: MatTable, static: false }) dataTable: any;

  @Input() public formDataArray;

  public dataArray = [];

  displayedColumns: string[] = ['position', 'name', 'surname', 'age', 'action'];

constructor(public dialog: MatDialog, private _visualService: VisualService) { }

  openDialog(customer) {
    this.dialog.open(DialogComponent);
  }

  ngOnInit() {
    this._visualService.currentArray
      .subscribe(arrayData => {
        this.dataArray=arrayData
        console.log(this.dataArray)
        //this.dataTable.renderRows(); -- this is the line that i want to use to redraw a Angular Mat table...but it displays that the table is undefined...//

      });
  }

【问题讨论】:

  • 不要告诉我们您尝试了什么,显示您尝试过的代码。谢谢。

标签: angular typescript


【解决方案1】:

使用 mat-table 时,实际上应该将 observable 直接连接到数据源,而不是将其存储在数组中。无需自己处理订阅,材料表将为您处理。

组件:

constructor(readonly dialog: MatDialog, readonly visualService: VisualService) { }

模板:

<table mat-table [datasource]="visualService.currentArray">
  ...
</table>

原创

您要做的是创建一个全局服务,并在该服务中指定一个主题。在需要从中触发的任何组件中订阅主题。单击按钮时,更新主题。

服务

private readonly source = new Subject<any[]>();
readonly dataChanged = this.source.asObservable();

updateData(data: any[]) {
  this.source.next(data);
}

附:确保在组件销毁时取消订阅主题,我建议使用 takeUntil 模式。

/** Handle on-destroy Subject, used to unsubscribe. */
private readonly destroyed = new ReplaySubject<void>(1);

ngOnInit() {
  this.service.dataChanged.takeUntil(this.destroyed).subscribe(
    (data: any[]) => {
      // Do what you need here
    }
  );
}

ngOnDestroy() {
  // Unsubscribes all pending subscriptions.
  this.destroyed.next();
}

【讨论】:

  • 您好,感谢您的快速回答。我尝试了类似的方法但没有奏效。我将使用代码编辑上面的帖子。
  • @StevenK。看到您使用的是 Angular Material Table,应该实现的方式会发生一些变化(并且变得更容易)。我已经更新了我的答案以反映这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
相关资源
最近更新 更多