Angular 如何将排序添加到mat列表中?

Angular 如何将排序添加到mat列表中?,angular,typescript,list,angular-material,Angular,Typescript,List,Angular Material,我找到了很多解决方案,但没有一个是使用mat list的。 这对我来说是必要的,因为mat list是拖放工作的唯一解决方案(table had mat table对我来说总是有问题,我找不到解决方案如何解决它)。我的html中有一部分是使用拖放功能从工作垫列表中提取的,但不知道如何添加排序: <div *ngIf="viewList" fxFlex class="list-borders"> <mat-list cdkDropList (cdkDropListDrop

我找到了很多解决方案,但没有一个是使用mat list的。 这对我来说是必要的,因为mat list是拖放工作的唯一解决方案(table had mat table对我来说总是有问题,我找不到解决方案如何解决它)。我的html中有一部分是使用拖放功能从工作垫列表中提取的,但不知道如何添加排序:

<div *ngIf="viewList" fxFlex class="list-borders">
    <mat-list cdkDropList (cdkDropListDropped)="drop($event)">
      <mat-list-item>
        <mat-grid-list cols="16" rowHeight="50px" fxFlex  class="title-row">
          <mat-grid-tile colspan="4" class="title-tile">
            Name
          </mat-grid-tile> 
          <mat-grid-tile class="title-tile">
            Extension
          </mat-grid-tile> 
          <mat-grid-tile class="title-tile">
            Status
          </mat-grid-tile> 
          <mat-grid-tile class="title-tile">
            Size
          </mat-grid-tile> 
          <mat-grid-tile colspan="2" class="title-tile">
            Server version
          </mat-grid-tile> 
          <mat-grid-tile colspan="5" class="title-tile">
            Last modified (server)
          </mat-grid-tile> 
          <mat-grid-tile colspan="2">
            Segment name
          </mat-grid-tile>
        </mat-grid-list>
      </mat-list-item>
      <mat-list-item cdkDrag *ngFor="let element of Elements" (click)="navigate(element)" (contextmenu)="onContextMenu($event, element)" >
        <mat-grid-list cols="16" rowHeight="50px" fxFlex>
          <mat-grid-tile colspan="4">
            <mat-icon *ngIf="element.isFolder" color="primary">
              folder
            </mat-icon>
            <mat-icon *ngIf="!element.isFolder" color="primary">
              insert_drive_file
            </mat-icon>
            {{element.name}}
          </mat-grid-tile>
          <mat-grid-tile>
            {{element.extension}}
          </mat-grid-tile>
          <mat-grid-tile>
            <mat-icon *ngIf="element.status == 'online'" class="status-online">
              check_circle
            </mat-icon>
            <mat-icon *ngIf="element.status == 'unknown'" class="status-unknown">
              help
            </mat-icon>
            <mat-icon *ngIf="element.status == 'offline'" class="status-offline">
              report_problem
            </mat-icon>
          </mat-grid-tile>
          <mat-grid-tile>
            {{element.size}}
          </mat-grid-tile>
          <mat-grid-tile colspan="2">
            {{element.serverVersion}}
          </mat-grid-tile>
          <mat-grid-tile colspan="5">
            {{element.lastModified}}
          </mat-grid-tile>
          <mat-grid-tile colspan="2">
            {{element.segmentName}}
          </mat-grid-tile>
        </mat-grid-list>
      </mat-list-item>
    </mat-list>
  </div>
还有一些示例元素:

ngOnInit() {
    const folderA = this.fileService.add(
      { 
        name: 'Movies', 
        isFolder: true, 
        parent: 'root',
        status: 'online',
        size: 0,
        serverVersion: '5',
        lastModified: 'added yesterday',
        segmentName: 'IDK'
      }
    );
    this.fileService.add(
      { 
        name: 'Trash', 
        isFolder: true, 
        parent: 'root',
        status: 'unknown',
        size: 0,
        serverVersion: '22',
        lastModified: 'added 2 years ago',
        segmentName: 'WTF'
      }
    );
    this.fileService.add(
      { 
        name: 'how_to_fix_it', 
        isFolder: false, 
        parent: 'root',
        extension: '.txt',
        status: 'offline',
        size: 2048,
        serverVersion: '1',
        lastModified: 'added 1 week ago',
        segmentName: 'NI'
      }
    );
    this.fileService.add(
      { 
        name: 'cute', 
        isFolder: false, 
        parent: 'root',
        extension: '.jpg',
        status: 'online',
        size: 4096,
        serverVersion: '12',
        lastModified: 'added today',
        segmentName: 'WUT'
      }
    );
    const temp = (folderA.id as string);
    this.fileService.add(
      { 
        name: 'Game of thrones', 
        isFolder: true, 
        parent: temp,
        status: 'online',
        size: 0,
        serverVersion: '5',
        lastModified: 'added month ago',
        segmentName: 'OMG'
      }
    );
    this.updateFileElementQuery();
它们是作为投入而来的:

  @Input() elements: Element[];

我对您的代码进行了一些重构,以使其适应您不得不对其进行的不当使用(默认情况下使用dataTable进行排序更为正确)

当然,为此我为你将来的代码重构打下了基础。 html

<div *ngIf="true" fxFlex class="list-borders">

    <mat-grid-list cols="16" rowHeight="50px" class="title-row">
        <div class="flex">
            <mat-grid-tile *ngFor="let tile of tiles;" [colspan]="tile.cols" [rowspan]="tile.rows" [class]="tile.class"
                (click)="sortOnClick(tile);">
                <span class="flex"> {{tile.text}} <mat-icon>{{ !tile.direction ? 'arrow_drop_down' : 'arrow_drop_up' }}</mat-icon> </span>
            </mat-grid-tile>
        </div>
    </mat-grid-list>

    <div cdkDropList (cdkDropListDropped)="drop($event)" [cdkDropListData]="elements">
        <!-- (contextmenu)="onContextMenu($event, element)" -->
        <mat-list-item cdkDrag *ngFor="let element of elements">
            <mat-grid-list cols="16" rowHeight="50px" fxFlex>
                <mat-grid-tile colspan="4">
                    <mat-icon *ngIf="element.isFolder" color="primary">
                        folder
                    </mat-icon>
                    <mat-icon *ngIf="!element.isFolder" color="primary">
                        insert_drive_file
                    </mat-icon>
                    {{element.name}}
                </mat-grid-tile>
                <mat-grid-tile>
                    {{element.extension}}
                </mat-grid-tile>
                <mat-grid-tile>
                    <mat-icon *ngIf="element.status == 'online'" class="status-online">
                        check_circle
                    </mat-icon>
                    <mat-icon *ngIf="element.status == 'unknown'" class="status-unknown">
                        help
                    </mat-icon>
                    <mat-icon *ngIf="element.status == 'offline'" class="status-offline">
                        report_problem
                    </mat-icon>
                </mat-grid-tile>
                <mat-grid-tile>
                    {{element.size}}
                </mat-grid-tile>
                <mat-grid-tile colspan="2">
                    {{element.serverVersion}}
                </mat-grid-tile>
                <mat-grid-tile colspan="5">
                    {{element.lastModified}}
                </mat-grid-tile>
                <mat-grid-tile colspan="2">
                    {{element.segmentName}}
                </mat-grid-tile>
            </mat-grid-list>
        </mat-list-item>
    </div>
</div>

angular typescript list
shareeditflag
你可以在那里找到stackblitz:


如果您给我排序标准,我将为您创建一个stackblitz。排序标准是当您单击Name table header或Extension时。类似于带有排序标题的经典表。这在mat列表中是可能的?您能用一些数据更新您的问题吗?所以我可以用正确的方式重新创建您需要的数据?我可以提供一切必要的东西。我需要元素数据
<div *ngIf="true" fxFlex class="list-borders">

    <mat-grid-list cols="16" rowHeight="50px" class="title-row">
        <div class="flex">
            <mat-grid-tile *ngFor="let tile of tiles;" [colspan]="tile.cols" [rowspan]="tile.rows" [class]="tile.class"
                (click)="sortOnClick(tile);">
                <span class="flex"> {{tile.text}} <mat-icon>{{ !tile.direction ? 'arrow_drop_down' : 'arrow_drop_up' }}</mat-icon> </span>
            </mat-grid-tile>
        </div>
    </mat-grid-list>

    <div cdkDropList (cdkDropListDropped)="drop($event)" [cdkDropListData]="elements">
        <!-- (contextmenu)="onContextMenu($event, element)" -->
        <mat-list-item cdkDrag *ngFor="let element of elements">
            <mat-grid-list cols="16" rowHeight="50px" fxFlex>
                <mat-grid-tile colspan="4">
                    <mat-icon *ngIf="element.isFolder" color="primary">
                        folder
                    </mat-icon>
                    <mat-icon *ngIf="!element.isFolder" color="primary">
                        insert_drive_file
                    </mat-icon>
                    {{element.name}}
                </mat-grid-tile>
                <mat-grid-tile>
                    {{element.extension}}
                </mat-grid-tile>
                <mat-grid-tile>
                    <mat-icon *ngIf="element.status == 'online'" class="status-online">
                        check_circle
                    </mat-icon>
                    <mat-icon *ngIf="element.status == 'unknown'" class="status-unknown">
                        help
                    </mat-icon>
                    <mat-icon *ngIf="element.status == 'offline'" class="status-offline">
                        report_problem
                    </mat-icon>
                </mat-grid-tile>
                <mat-grid-tile>
                    {{element.size}}
                </mat-grid-tile>
                <mat-grid-tile colspan="2">
                    {{element.serverVersion}}
                </mat-grid-tile>
                <mat-grid-tile colspan="5">
                    {{element.lastModified}}
                </mat-grid-tile>
                <mat-grid-tile colspan="2">
                    {{element.segmentName}}
                </mat-grid-tile>
            </mat-grid-list>
        </mat-list-item>
    </div>
</div>

angular typescript list
shareeditflag
import { Component, ViewChild, ElementRef, ChangeDetectionStrategy, Pipe, PipeTransform, ChangeDetectorRef } from '@angular/core';
import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
import { orderBy } from 'lodash';

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

  elements = [
    {
      name: 'Movies',
      isFolder: true,
      parent: 'root',
      status: 'online',
      size: 0,
      serverVersion: '5',
      lastModified: 'added yesterday',
      segmentName: 'IDK'
    },
    {
      name: 'Trash',
      isFolder: true,
      parent: 'root',
      status: 'unknown',
      size: 0,
      serverVersion: '22',
      lastModified: 'added 2 years ago',
      segmentName: 'WTF'
    },
    {
      name: 'how_to_fix_it',
      isFolder: false,
      parent: 'root',
      extension: '.txt',
      status: 'offline',
      size: 2048,
      serverVersion: '1',
      lastModified: 'added 1 week ago',
      segmentName: 'NI'
    },
    {
      name: 'cute',
      isFolder: false,
      parent: 'root',
      extension: '.jpg',
      status: 'online',
      size: 4096,
      serverVersion: '12',
      lastModified: 'added today',
      segmentName: 'WUT'
    },
    {
      name: 'Game of thrones',
      isFolder: true,
      parent: 'temp',
      status: 'online',
      size: 0,
      serverVersion: '5',
      lastModified: 'added month ago',
      segmentName: 'OMG'
    }
  ];

  tiles = [
    { text: 'name', cols: 4, rows: 1, class: 'title-tile', direction: false },
    { text: 'extension', cols: 2, rows: 1, class: 'title-tile', direction: false },
    { text: 'status', cols: 2, rows: 1, class: 'title-tile', direction: false },
    { text: 'size', cols: 2, rows: 1, class: 'title-tile', direction: false },
    { text: 'serverVersion', cols: 2, rows: 1, class: 'title-tile', direction: false },
    { text: 'lastModified', cols: 5, rows: 1, class: 'title-tile', direction: false },
    { text: 'segmentName', cols: 2, rows: 1, class: 'title-tile', direction: false },
  ];

  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);
    }
  }

  constructor() {
  }

  sortOnClick(tile) {
    this.elements = orderBy(this.elements, [tile.text], [tile.direction ? 'asc' : 'desc']);
    tile.direction = !tile.direction
  }

}
.flex {
  display: flex;
}