Material table 数据源在 filteredData 属性 中存储数据而不是数据 属性

Material table datasource storing data in filteredData property instead of data property

在我的 angular 项目中,我在一个页面上有一个 table,其中包含银行账户列表及其余额和其他数据等(参考下图)。

我的目标是使 table 条目可点击,这样每次有人点击 table 中的一行时,另一个包含银行交易的组件 material table, Bank Ledger,在对话框中打开并显示相应银行帐户的记录,其行已在 Bank Balance table.

中单击

为此,我将帐号发送到服务中的一个函数,该函数将其推送到一个可观察的主题。并且银行分类账组件订阅了上述可观察对象。参考以下代码:

银行余额 table 的组成部分:

  constructor(private Fin:Finservice) {}

  acnum:number;

  viewBankLedger(): void {
    const dialogRef = this.dialog.open( BankledgerComponent , { width: '40vw', height: '80vh', disableClose: true, panelClass: "foo" } ); 
  }

  openLedger(row) {
    this.acnum = row.bank_acnum;
    this.Fin.getBankACNum(this.acnum);
    this.viewBankLedger();
  }

财务服务:

  private _subject = new Subject<any>();
  changebank = this._subject.asObservable();

  getBankACNum(acnum: number){
    this._subject.next(acnum);
  }

银行分类帐组件:

export class BankledgerComponent implements OnInit {

  constructor(private Fin: Finservice, private LS: LedgerService) {}

  ngOnInit() {
    this.Fin.changebank.subscribe( result => {
      this.acnum = result;
      const bankACNum = {
        acnum: this.acnum,
      };
      this.getLedger(bankACNum);  
    })
  }
  
  BankLedgerDataSource = new MatTableDataSource<BankLedger>();
  bankLedger: BankLedger[];
  acnum:number;
  ledgerColumns: string[] = ['serial', 'bl_date', 'bl_part', 'bl_debit', 'bl_credit', 'bl_balance'];

  getLedger(bankACNum:ACNum){
    this.LS.showBankLedger(bankACNum).subscribe((results:BankLedger[])=>{
      this.bankLedger = results;
      this.BankLedgerDataSource.data = this.bankLedger;
      console.log(this.BankLedgerDataSource);
    })
  }

}

银行分类帐模板:

<div mat-dialog-content style="background-color: white; border-radius: 5px; padding: 1%;">

        <table style="width: 100%;" mat-table [dataSource]="BankLedgerDataSource" class="mat-elevation-z8">
            
        <ng-container matColumnDef="serial">
            <th mat-header-cell *matHeaderCellDef> S.No. </th>
            <td mat-cell *matCellDef="let element; let i = index;"> {{i+1}} </td>
        </ng-container>
                
        <ng-container matColumnDef="bl_date">
            <th mat-header-cell *matHeaderCellDef> Date </th>
            <td mat-cell *matCellDef="let element">{{element.bl_date | date:'dd/MM/yyyy'}} </td>
        </ng-container>
                
        <ng-container matColumnDef="bl_part">
            <th mat-header-cell *matHeaderCellDef> Particulars </th>
            <td mat-cell *matCellDef="let element"> {{element.bl_part}} </td>
        </ng-container>

        <ng-container matColumnDef="bl_debit">
            <th mat-header-cell *matHeaderCellDef> Debit Amount</th>
            <td mat-cell *matCellDef="let element"> {{element.bl_debit  | INRCurrency}} </td>
        </ng-container>

        <ng-container matColumnDef="bl_credit">
            <th mat-header-cell *matHeaderCellDef> Credit Amount</th>
            <td mat-cell *matCellDef="let element"> {{element.bl_credit  | INRCurrency}} </td>
        </ng-container>
            
        <ng-container matColumnDef="bl_balance">
            <th mat-header-cell *matHeaderCellDef> Balance </th>
            <td mat-cell *matCellDef="let element"> {{element.bl_balance  | CreditDebit}} </td>
        </ng-container>

        <tr mat-header-row *matHeaderRowDef="ledgerColumns"></tr>
        <tr class="tablerow" mat-row *matRowDef="let row; columns: ledgerColumns;"> </tr>

    </table>
La la la
</div>

<div mat-dialog-actions style="margin-top: 2%; border-top: 1px solid black;">
    <button type="button" class="btn btn-outline-dark" [mat-dialog-close]="true">Close</button>
</div>

正如您在上面看到的,已经订阅了主题,创建了一个 json 包并将其发送到一个方法,该方法使用另一个服务(称为 Ledger Service)从 api 检索相应的数据。

export class LedgerService {

  constructor(private httpClient: HttpClient) { }
  
showBankLedger(acnum: ACNum): Observable<BankLedger[]> {
    return this.httpClient.post<any>(`${this.PHP_API_SERVER}/apiroute.php`, acnum);
  }

虽然一切都应该工作正常,但我面临着多个问题,上帝知道为什么。这是我面临的问题:

  1. 包含银行余额 table 的组件首次加载后;我第一次单击任何行时,弹出对话框但数据似乎没有通过,因为控制台中没有日志。

  2. 关闭对话框后,再次单击,数据似乎进入了银行分类帐组件,但 table 没有显示任何数据。此外,数据存储在 MatDataSource 的 filteredData 属性 中。

  1. 第三次点击之后的结果相同,但有一个例外;第 3 次单击后,控制台记录数据 2 次而不是 1 次。在第 4 次单击时,数据记录 3 次。它继续如此等等。

请帮忙。我被难住了。

我找到了解决方案,虽然不是很好,但一切都一样。

按照@tony 的建议,我尝试使用更改检测器但无济于事。没有尝试他随后建议的 *ngIf 方法,因为我知道它不会起作用,至少不会像我希望的那样起作用。我确实在我的解决方案中使用 async/await。

在我的问题中,我使用一个组件将帐号发送到服务。然后该服务通过可观察对象将数据传递给另一个组件,然后该组件再次将相同的数据发送到另一个不同的服务以从 api.

获取所需的数据

我避免了这种杂耍,只是将 acnum 发送到服务。然后从服务本身的 api 中获取所需的数据。从那里开始很容易。只是将数组发送到另一个组件,在 onInit 和 wallah 中订阅,事情开始像魅力一样工作。更新了以下代码:

Fin 组件

  viewBankLedger(): void {
    const dialogRef = this.dialog.open( BankledgerComponent , { width: '40vw', height: '80vh', disableClose: true, panelClass: "foo" } ); 
  }

  openLedger(row) {
    this.acnum = row.bank_acnum;
    this.service.getBankACNum(this.acnum);
    this.viewBankLedger();
  }

服务

  private _subject = new Subject<any>();
  changebank =  this._subject.asObservable();
  sendBankLedger(result){
    this._subject.next(result);
  }
  
  async getBankACNum(acnum) { 
    const bankACNum = {
      acnum: acnum,
    };
    const data = await this.http.post<any>(`${this.PHP_API_SERVER}/api/fin/readbankledger.php`, bankACNum).toPromise();
    this.results = data;
    console.log(this.results);
    this.sendBankLedger(this.results);
  }
 

银行分类帐组件(在对话框中打开)

  ngOnInit() {
    this.service.changebank.subscribe(results=>{
      this.bankLedger = results;
      console.log(this.bankLedger);
      this.BankLedgerDataSource.data = this.bankLedger;
    });
  }
  
  BankLedgerDataSource = new MatTableDataSource<BankLedger>();
  bankLedger: BankLedger[];

如果没有 async/await,此解决方案将不起作用。希望有人觉得它有用。