angular - درج کامپوننت در زیر ردیف جدول mat تنها در یک ستون درج میشود


من انتظار دارم که مؤلفه در سراسر کل ردیف قرار گیرد. در عوض، به نظر میرسد مؤلفه در ستون اول ردیف جدید قرار گرفته است.

در اینجا یک مثال قابل بازتولید در Angular 9 آمده است: https://stackblitz.com/edit/angular-ithddx من ابتدا با این مشکل در Angular 8 با استفاده از @angular/material 8.2.3 مواجه شدم.

کلیک کردن روی ردیف اول، المان را وارد میکند، اما به جای استفاده از کل ردیف جدید ایجاد شده، ستون اول را گسترش میدهد.

app.component.html:

<div class="example-container mat-elevation-z8">
  <table mat-table #table [dataSource]="dataSource">

    <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->

    <!-- Position Column -->
    <ng-container matColumnDef="position">
      <th mat-header-cell *matHeaderCellDef> No. </th>
      <td mat-cell *matCellDef="let element"> {{element.position}} </td>
    </ng-container>

    <!-- Name Column -->
    <ng-container matColumnDef="name">
      <th mat-header-cell *matHeaderCellDef> Name </th>
      <td mat-cell *matCellDef="let element"> {{element.name}} </td>
    </ng-container>

    <!-- Weight Column -->
    <ng-container matColumnDef="weight">
      <th mat-header-cell *matHeaderCellDef> Weight </th>
      <td mat-cell *matCellDef="let element"> {{element.weight}} </td>
    </ng-container>

    <!-- Symbol Column -->
    <ng-container matColumnDef="symbol">
      <th mat-header-cell *matHeaderCellDef> Symbol </th>
      <td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns; let index = index" 
      (click)="insertComponent(index)"
      #tableRow>
    </tr>
  </table>
</div>

app.component.ts:

    import {Component, ViewChildren, ViewContainerRef, ComponentFactoryResolver, ComponentFactory, Input} from '@angular/core';
    import {MatTableDataSource} from '@angular/material/table';

    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  {
      displayedColumns = ['position', 'name', 'weight', 'symbol'];
      dataSource = new MatTableDataSource<Element>(ELEMENT_DATA);

      @ViewChildren('tableRow', { read: ViewContainerRef }) rowContainers;
      expandedRow: number;

      constructor(private resolver: ComponentFactoryResolver) { }

      insertComponent(index: number) {
        if (this.expandedRow != null) {
          // clear old content
          this.rowContainers.toArray()[this.expandedRow].clear();
        }

        if (this.expandedRow === index) {
          this.expandedRow = null;
        } else {
          const container = this.rowContainers.toArray()[index];
          const factory: ComponentFactory<any> = this.resolver.resolveComponentFactory(InlineMessageComponent);
          const inlineComponent = container.createComponent(factory);

          inlineComponent.instance.user = this.dataSource.data[index].name;
          inlineComponent.instance.weight = this.dataSource.data[index].weight;
          this.expandedRow = index;
        }
      }
    }

InlineMessageComponent.ts

/*
* The component that will be dynamically rendered between table rows
*/ 
@Component({
  selector: 'app-inline-message',
  template: '<p>Name: {{ user }} |</p><p>| weight {{ weight }}</p>',
  styles: [`
    :host {
      display: flex;
      place-content:center;
      padding: 24px;
      color: #555555;
      font-weight: bold;
      background: rgba(0,0,0,0.1);
    }
  `]
})
export class InlineMessageComponent {
  @Input() user: string;
  @Input() weight: string;
}

من انتظار دارم رفتار مشابه این مثال Angular 5 که دنبال میکردم را ببینم. https://stackblitz.com/edit/angular-yxznk8-rongna

کارهایی که امتحان شد:

  • جایگزینی <tr mat-row> با <mat-row>
  • استفاده از MatTableDataSource و درج ردیفهای جدید

    • این روش باعث میشود استایل دادن به ردیف جدید دشوار شود
    • کد بسیار بیشتر
    • ردیف جدید حتی زمانی که خالی است نمایش داده میشود

پاسخ شماره ۱

تمام کاری که باید انجام دهید، این است که HTML را در نشانهگذاری خود قرار دهید و به دستورالعملهای Angular پایبند باشید:

<div class="example-container mat-elevation-z8">
  <mat-table #table [dataSource]="dataSource">

    <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->

    <!-- Position Column -->
    <ng-container matColumnDef="position">
      <mat-header-cell *matHeaderCellDef> No. </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.position}} </mat-cell>
    </ng-container>

    <!-- Name Column -->
    <ng-container matColumnDef="name">
      <mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
    </ng-container>

    <!-- Weight Column -->
    <ng-container matColumnDef="weight">
      <mat-header-cell *matHeaderCellDef> Weight </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.weight}} </mat-cell>
    </ng-container>

    <!-- Symbol Column -->
    <ng-container matColumnDef="symbol">
      <mat-header-cell *matHeaderCellDef> Symbol </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.symbol}} </mat-cell>
    </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns; let index = index" 
      (click)="insertComponent(index)"
      #tableRow>
    </mat-row>
  </mat-table>
</div>

مثال آسانتر برای تجزیه:

  <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>

به جای

   <tr mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>