Угловой 4 Таблица материалов выделяет ряд

Я ищу хороший способ выделить всю строку в md-таблице.
Должен ли я делать директиву или что?
Кто-нибудь может мне помочь?

<div class="example-container mat-elevation-z8">
  <md-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" -->

    <!-- ID Column -->
    <ng-container cdkColumnDef="userId">
      <md-header-cell *cdkHeaderCellDef> ID </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.id}} </md-cell>
    </ng-container>

    <!-- Progress Column -->
    <ng-container cdkColumnDef="progress">
      <md-header-cell *cdkHeaderCellDef> Progress </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.progress}}% </md-cell>
    </ng-container>

    <!-- Name Column -->
    <ng-container cdkColumnDef="userName">
      <md-header-cell *cdkHeaderCellDef> Name </md-header-cell>
      <md-cell *cdkCellDef="let row"> {{row.name}} </md-cell>
    </ng-container>

    <!-- Color Column -->
    <ng-container cdkColumnDef="color">
      <md-header-cell *cdkHeaderCellDef>Color</md-header-cell>
      <md-cell *cdkCellDef="let row" [style.color]="row.color"> {{row.color}} </md-cell>
    </ng-container>

    <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
    <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>
  </md-table>
</div>

Таблица из: https://material.angular.io/components/table/overview

Ответы

Ответ 1

Обновление для новой версии материала (md → mat):

HTML:

<!-- Add the highlight class in row definiton of md-table -->
<!-- Add click event to pass the selected row index -->

<mat-row *cdkRowDef="let row; columns: displayedColumns;" 
         [ngClass]="{'highlight': selectedRowIndex == row.id}"
         (click)="highlight(row)">
</mat-row>

Оригинальный ответ:

Вы можете сделать это, используя ngClass и флаг, подобный selectedRowIndex. Всякий раз, когда щелкнутый индекс строки равен selectedRowIndex, класс будет применен.

Демо-версия Plunker

HTML:

<!-- Add the highlight class in row definiton of md-table -->
<!-- Add click event to pass the selected row index -->

<md-row *cdkRowDef="let row; columns: displayedColumns;" 
         [ngClass]="{'highlight': selectedRowIndex == row.id}"
         (click)="highlight(row)">
</md-row>

CSS:

.highlight{
  background: #42A948; /* green */
}

TS:

selectedRowIndex: number = -1;

highlight(row){
    this.selectedRowIndex = row.id;
}

Ответ 2

На странице примеров обзора таблицы они объясняют SelectionModel для обработки выбора, который, кстати, также обрабатывает множественный выбор. Я предполагаю, что в будущем это будет включено в будущие улучшения, поэтому неплохо начать использовать его сейчас.

selection - это SelectionModel, определенный в вашем компоненте. Я не мог найти никакой реальной документации для этого, но реализация чрезвычайно проста.

selection = new SelectionModel<CustomerSearchResult>(false, null);

Первый параметр allowMultiSelect, поэтому для одновременного выбора нескольких элементов устанавливается значение true. Когда false, модель выбора отменяет выделение любых существующих значений при установке нового значения.

Затем добавьте событие click, чтобы select() строку и создать свой собственный класс css для выбора строки.

   <mat-table>
        ...

        <mat-row *matRowDef="let row; columns: displayedColumns;"
                 [ngClass]="{ 'selected': selection.isSelected(row)}"
                 (click)="selection.select(row)"></mat-row>

    </mat-table>

Класс css, который я добавил, ниже (образец еще не упоминает стилизацию), а затем вам просто нужно добавить к вашему css

.mat-row {
   min-height: 65px;

   &.selected {
       background: #dddddd;
   }
}

Если ваш фоновый цвет слишком темный, вам нужно добавить стили самостоятельно, чтобы инвертировать цвет текста.

Для обработки выбора используйте событие selection onChange.

    // selection changed
    this.selection.onChange.subscribe((a) =>
    {
        if (a.added[0])   // will be undefined if no selection
        {
            alert('You selected ' + a.added[0].fullName);
        }
    });

Или, альтернативно, выбранные элементы находятся в this.selection.selected.

Я надеюсь, что mat-table улучшится для обычных случаев, подобных этому, и они не просто оставят все до разработчика. Такие вещи, как клавиатурные события и т.д., Были бы удобны для обработки автоматически в отношении модели выбора.


Совет. Обратите внимание, что если вы создадите свой SelectionModel для коллекции, отличной от нескольких элементов, с помощью

selection = new SelectionModel<CustomerSearchResult>(false, []);

Тогда selection.selected.length будет фактически 1, а не ожидаемыми 0 элементами. Нет никакой проверки, чтобы увидеть, что элемент, переданный в действительности, действительно находится в модели - это очень очень немой класс. Поэтому он слепо ставит [0] в качестве выбранного элемента. Вместо этого используйте null. Исходный код дает понять, почему это происходит:

if (_isMulti) {
    initiallySelectedValues.forEach(value => this._markSelected(value));
  } else {
    this._markSelected(initiallySelectedValues[0]);
  }

Ответ 3

Итак, я столкнулся с этой проблемой. Я использую новый "mat-" вместо "md-", но я УГАДАЮ, что он будет примерно таким же...

<mat-row
    *matRowDef="let row; columns: myColumns; let entry"
    [ngClass]="{ 'my-class': entry.someVal }">
</mat-row>

Я этого нигде не нашел, я просто попробовал, и это случилось, и я надеюсь, что так. Большая вещь заключалась в том, чтобы пометить "let entry" до конца другого материала matRowDef. Извините, я так опаздываю на вечеринку. Надеюсь, это кому-то помогает.

Ответ 4

У меня не было уникальных идентификаторов, таких как столбец идентификаторов в моих табличных данных, но это сработало для меня (материал 6):

HTML

 <tr mat-row *matRowDef="let row; columns: displayedColumns" 
     (click)="selectedRow = row" [ngClass]="{ 'selected': row === selectedRow }"> 
 </tr>

добавить переменную в TS

selectedRow;

(S) CSS

.selected {
  background-color: red;
}

Если вы хотите сделать больше вещей, чем просто стиль при выборе строки, замените (click)="selectedRow = row" с помощью (click)="selectRow(row)" и добавьте эту функцию в ts:

selectRow(row) {
    this.selectedRow = row;
    // more stuff to do...
}