Как мне остановить это странное взаимодействие между CdkDropList и таблицей материалов - PullRequest
1 голос
/ 16 мая 2019

Я использую таблицу материалов для отображения некоторых данных и использую CdkDropList для возможности перегруппировки используемых столбцов / переключения столбцов в отдельном компоненте (диалоговое окно с матом).

Проблема в том, что CdkDropList и таблица Material связаны каким-либо образом. Всякий раз, когда я переставляю / выключаю колонки в CdkDropList, колонки переставляют / выключают в реальном времени в таблице материалов. Это звучит фантастически, но я не хочу, чтобы это происходило, если я пытаюсь сохранить конфигурацию столбцов в базе данных, которая срабатывает при нажатии кнопки, а не в режиме реального времени.

Я абсолютно не знаю, как это происходит, но, надеюсь, кто-то видит что-то, чего не вижу я ...

Вот компонент таблицы и компонент диалога:

Вот компонент диалога:

      <div class="column-list-container" cdkDropListGroup>

        <p class="options-text">Columns in use</p>
        <div class="label-list-container">
          <div cdkDropList [cdkDropListData]="columns" cdkDropListOrientation="horizontal" class="label-list"
            (cdkDropListDropped)="drop($event)">
            <div class="label" *ngFor="let column of columns" cdkDrag>
              {{ column }}
            </div>
          </div>
        </div>

        <p class="options-text">Unused Columns</p>
        <div class="label-list-container">
          <div cdkDropList [cdkDropListData]="unusedColumns" cdkDropListOrientation="horizontal" class="label-list"
            (cdkDropListDropped)="drop($event)">
            <div class="label" *ngFor="let column of unusedColumns" cdkDrag>
              {{ column }}
            </div>
          </div>
        </div>

      </div>
  widget: Widget;
  columns: string[];
  unusedColumns: string[];

  constructor(
    public dialogRef: MatDialogRef<ConfigWidgetDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any
  ) { }

  ngOnInit() {
    this.widget = this.data.widget;
    this.columns = this.widget.options.columns;
    this.unusedColumns = this.widget.options.unusedColumns;
  }

  drop(event: CdkDragDrop<string[]>) {

    if (event.previousContainer === event.container) {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex);
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex);
    }
  }

  closeDialog(options: any): void {
    if (options) {
      this.widget.options.title = options.title;
      this.widget.options.columns = this.columns;
      this.widget.options.unusedColumns = this.unusedColumns;

      this.dialogRef.close(this.widget);
    } else {
      this.dialogRef.close();
    }
  }

и теперь компонент таблицы:

  <div class="data-table">
    <!-- Material table component -->
    <table mat-table class="table" [dataSource]="dataSource" matSort aria-label="Elements">
      <!-- Generates Column Names -->
      <ng-container *ngFor="let col of displayedColumns" matColumnDef="{{ col }}">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>{{ col }}</th>
        <td class="table-cell" mat-cell *matCellDef="let row">
          {{ row[col] }}
        </td>
      </ng-container>

      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row class="table-row" *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>
  </div>

  <mat-paginator class="paginator" #paginator [length]="dataSource.data.length" [pageIndex]="0" [pageSize]="5"
    [pageSizeOptions]="[5, 10, 20, 50]">
  </mat-paginator>
  // material table
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
  dataSource: MatTableDataSource<any> = new MatTableDataSource();
  displayedColumns: string[] = [];

  @Input() widgetInfo: any;

  constructor(
    private data: DataService,
    private stateService: StateService
  ) { }

  ngOnInit() {

    this.stateService.state.pipe(
      map(state => {
        return state.pages[this.widgetInfo.page].widgets[`${this.widgetInfo.type}${this.widgetInfo.id}`];
      }),
      filter((widget) => !!widget),
      switchMap(widget => {
        this.displayedColumns = widget.options.columns;
        return this.data.getData(widget.options.databaseTable, widget.options.preset);
      })
    ).subscribe(response => {
      this.dataSource.data = response;
      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;
      if (response.length === 0) {
        this.noResults = true;
      }
      this.isLoadingResults = false;
    }, error => {
      console.log(error);
      this.isLoadingResults = false;
      this.errorResults = true;
    });

  }

1 Ответ

0 голосов
/ 16 мая 2019

Вы назначаете displayColumns со значением widget.options.columns. Это вызывается, вероятно, также при изменении порядка столбцов.

И столбцы вашей таблицы связаны с одной и той же переменной displayColumns. Вот почему они синхронизированы.

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

Вы можете иметь отдельный массив строк с неповрежденным порядком и связать его с matRowDef и matHeaderRowDef, чтобы сохранить порядок столбцов таблицы без изменений.

...