Mat-table Sorting Demo ไม่ทำงาน


114

ฉันพยายามทำให้การmat-tableเรียงลำดับทำงานในเครื่องและในขณะที่ฉันสามารถรับข้อมูลให้แสดงได้ตามที่คาดไว้การคลิกที่แถวส่วนหัวจะไม่ทำการเรียงลำดับเหมือนในตัวอย่างออนไลน์ (ไม่มีอะไรเกิดขึ้นเลย) ฉันกำลังพยายามทำให้การสาธิตนี้ทำงานในเครื่อง: https://material.angular.io/components/sort/overview https://plnkr.co/edit/XF5VxOSEBxMTd9Yb3ZLA?p=preview

ฉันได้สร้างโปรเจ็กต์ใหม่ด้วย Angular CLI แล้วทำตามขั้นตอนต่อไปนี้: https://material.angular.io/guide/getting-started

นี่คือไฟล์ในเครื่องของฉัน:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { MatSort, MatTableModule } from '@angular/material';

import { AppComponent } from './app.component';
import { TableSortingExample } from './table-sorting-example';

@NgModule({
  declarations: [
    AppComponent,
    TableSortingExample,
    MatSort
  ],
  imports: [
    BrowserModule,
    MatTableModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';

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

app.component.html

<div style="text-align:center">
  <h1>
    Welcome to {{title}}!
  </h1>
  <table-sorting-example></table-sorting-example>
</div>

table-sorting-example.html

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

    <!--- 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 matColumnDef="userId">
      <mat-header-cell *matHeaderCellDef mat-sort-header> ID </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.id}} </mat-cell>
    </ng-container>

    <!-- Progress Column -->
    <ng-container matColumnDef="progress">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Progress </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.progress}}% </mat-cell>
    </ng-container>

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

    <!-- Color Column -->
    <ng-container matColumnDef="color">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Color </mat-header-cell>
      <mat-cell *matCellDef="let row" [style.color]="row.color"> {{row.color}} </mat-cell>
    </ng-container>

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


<!-- Copyright 2017 Google Inc. All Rights Reserved.
    Use of this source code is governed by an MIT-style license that
    can be found in the LICENSE file at http://angular.io/license -->

table-sorting-example.ts

import {Component, ViewChild} from '@angular/core';
import {DataSource} from '@angular/cdk/collections';
import {MatSort} from '@angular/material';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';

/**
 * @title Table with sorting
 */
@Component({
  selector: 'table-sorting-example',
  styleUrls: ['table-sorting-example.css'],
  templateUrl: 'table-sorting-example.html',
})
export class TableSortingExample {
  displayedColumns = ['userId', 'userName', 'progress', 'color'];
  exampleDatabase = new ExampleDatabase();
  dataSource: ExampleDataSource | null;

  @ViewChild(MatSort) sort: MatSort;

  ngOnInit() {
    this.dataSource = new ExampleDataSource(this.exampleDatabase, this.sort);
  }
}

/** Constants used to fill up our data base. */
const COLORS = ['maroon', 'red', 'orange', 'yellow', 'olive', 'green', 'purple',
  'fuchsia', 'lime', 'teal', 'aqua', 'blue', 'navy', 'black', 'gray'];
const NAMES = ['Maia', 'Asher', 'Olivia', 'Atticus', 'Amelia', 'Jack',
  'Charlotte', 'Theodore', 'Isla', 'Oliver', 'Isabella', 'Jasper',
  'Cora', 'Levi', 'Violet', 'Arthur', 'Mia', 'Thomas', 'Elizabeth'];

export interface UserData {
  id: string;
  name: string;
  progress: string;
  color: string;
}

/** An example database that the data source uses to retrieve data for the table. */
export class ExampleDatabase {
  /** Stream that emits whenever the data has been modified. */
  dataChange: BehaviorSubject<UserData[]> = new BehaviorSubject<UserData[]>([]);
  get data(): UserData[] { return this.dataChange.value; }

  constructor() {
    // Fill up the database with 100 users.
    for (let i = 0; i < 100; i++) { this.addUser(); }
  }

  /** Adds a new user to the database. */
  addUser() {
    const copiedData = this.data.slice();
    copiedData.push(this.createNewUser());
    this.dataChange.next(copiedData);
  }

  /** Builds and returns a new User. */
  private createNewUser() {
    const name =
      NAMES[Math.round(Math.random() * (NAMES.length - 1))] + ' ' +
      NAMES[Math.round(Math.random() * (NAMES.length - 1))].charAt(0) + '.';

    return {
      id: (this.data.length + 1).toString(),
      name: name,
      progress: Math.round(Math.random() * 100).toString(),
      color: COLORS[Math.round(Math.random() * (COLORS.length - 1))]
    };
  }
}

/**
 * Data source to provide what data should be rendered in the table. Note that the data source
 * can retrieve its data in any way. In this case, the data source is provided a reference
 * to a common data base, ExampleDatabase. It is not the data source's responsibility to manage
 * the underlying data. Instead, it only needs to take the data and send the table exactly what
 * should be rendered.
 */
export class ExampleDataSource extends DataSource<any> {
  constructor(private _exampleDatabase: ExampleDatabase, private _sort: MatSort) {
    super();
  }

  /** Connect function called by the table to retrieve one stream containing the data to render. */
  connect(): Observable<UserData[]> {
    const displayDataChanges = [
      this._exampleDatabase.dataChange,
      this._sort.sortChange,
    ];

    return Observable.merge(...displayDataChanges).map(() => {
      return this.getSortedData();
    });
  }

  disconnect() {}

  /** Returns a sorted copy of the database data. */
  getSortedData(): UserData[] {
    const data = this._exampleDatabase.data.slice();
    if (!this._sort.active || this._sort.direction == '') { return data; }

    return data.sort((a, b) => {
      let propertyA: number|string = '';
      let propertyB: number|string = '';

      switch (this._sort.active) {
        case 'userId': [propertyA, propertyB] = [a.id, b.id]; break;
        case 'userName': [propertyA, propertyB] = [a.name, b.name]; break;
        case 'progress': [propertyA, propertyB] = [a.progress, b.progress]; break;
        case 'color': [propertyA, propertyB] = [a.color, b.color]; break;
      }

      let valueA = isNaN(+propertyA) ? propertyA : +propertyA;
      let valueB = isNaN(+propertyB) ? propertyB : +propertyB;

      return (valueA < valueB ? -1 : 1) * (this._sort.direction == 'asc' ? 1 : -1);
    });
  }
}


/**  Copyright 2017 Google Inc. All Rights Reserved.
 Use of this source code is governed by an MIT-style license that
 can be found in the LICENSE file at http://angular.io/license */

ใครมีความคิดว่าทำไมมันถึงแสดงเหมือนตารางออนไลน์ แต่ไม่มีฟังก์ชันการเรียงลำดับ?


ฉันจะแก้ไขข้อบกพร่องของแอปก่อน ข้อผิดพลาดใด ๆ เรียกใช้ng test --sm=falseและดูว่ามีอะไรออกมา
k.vincent

มันใช้งานได้สำหรับฉันโดยไม่ต้องเรียงลำดับ @ViewChild (MatSort): MatSort; เหตุผลใด?
user123456

คำตอบ:


209

สำหรับใครก็ตามที่อาจมีปัญหานี้: ปัญหาคือฉันไม่ได้อ่านการอ้างอิง API อย่างถูกต้องบนเว็บไซต์วัสดุเชิงมุมส่วนที่ระบุว่าฉันต้องนำเข้า MatSortModule หลังจากที่ฉันเปลี่ยนรายการนำเข้าในapp.module.tsเป็น

imports: [
    BrowserModule,
    MatTableModule,
    MatSortModule
  ],

มันทำงานได้ดี


47
ไม่มีการกล่าวถึงโมดูลนี้ในเอกสารประกอบ material.angular.io/components/table/overview#sorting ฉันเสียเวลาไปหนึ่งชั่วโมงกับเรื่องนี้เช่นกัน
Sonic Soul

9
ไม่เป็นไรในข้อความส่วนหัวสามารถคลิกได้และไอคอนก็อยู่ที่นั่นด้วย แต่การเรียงลำดับยังไม่ทำงาน
SPnL

3
ตรวจสอบว่าBrowserAnimationsModuleมีการนำเข้าใน app.module.ts ด้วยหรือไม่
Augustas

2
ฉันสามารถบอกว่าพวกเขาเป็น SOBs ได้หรือไม่? ฉันใช้เวลา 1 ชั่วโมงในการพยายามหาสาเหตุที่ ViewChild ของฉันไม่ทำงาน พวกเขาไม่สามารถนำเข้า / ส่งออก MatSortModule นี้จาก MatTableModule ได้หรือไม่?
Sampgun

7
ฉันได้นำเข้าMatSortModuleและBrowserAnimationsModuleและฉันมั่นใจว่าค่า matColumnDef ตรงกับชื่อคุณสมบัติ แต่ฉันก็ยังไม่สามารถทำอะไรได้
Trevor

147

ฉันมีปัญหาว่าฟังก์ชันการเรียงลำดับใช้งานได้ แต่เรียงลำดับไม่ถูกต้อง ฉันตระหนักว่าmatColumnDefจะต้องมีชื่อเดียวกันของทรัพย์สินของฉันที่ฉันอ้างอิงในclass / interfacematCellDef

ตามเอกสาร Angular Material :

ตามค่าเริ่มต้น MatTableDataSource จะเรียงลำดับโดยสมมติว่าชื่อคอลัมน์ที่เรียงลำดับตรงกับชื่อคุณสมบัติข้อมูลที่คอลัมน์แสดง

สำหรับตัวอย่าง:

<ng-container matColumnDef="name"> 
    <mat-header-cell *matHeaderCellDef mat-sort-header> NAME </mat-header-cell>
    <mat-cell *matCellDef="let row"> {{row.name}} </mat-cell>
</ng-container>

nameในmatColumnDefคำสั่งจะต้องมีเช่นเดียวกับnameที่ใช้ใน<mat-cell>องค์ประกอบ


1
คุณกำลังอ้างถึงอะไรในตัวอย่างของคุณ? การดูอินเทอร์เฟซของคุณจะเป็นประโยชน์เช่นกันเพื่อเปรียบเทียบ
isherwood

1
ฉันใช้ "Id" เป็นชื่อคอลัมน์ในขณะที่เอนทิตีมี "id" ความแตกต่างของเคสทำให้มันไม่ทำงาน (เนื่องจากการ refactoring พลาด) .. ตอนนี้แก้ไขได้แล้ว ขอบคุณ
NitinSingh

2
ขอบคุณมันมีประโยชน์มาก
Bohao LI

2
@NitinSingh ถ้าคุณต้องการเรียกใช้ฟังก์ชันelementเช่นนี้ `{{row.getName ()}}`
codentary

2
ฉันเป็นหนี้เบียร์คุณโดยสิ้นเชิงเพราะฉันติดปัญหานี้มาระยะหนึ่งแล้วและความคิดเห็นนี้ช่วยแก้ปัญหาของฉันได้
noel

108

ถ้าตารางอยู่ใน * ngIf มันจะไม่ทำงาน จะใช้งานได้ถ้าเปลี่ยนเป็น [hidden]


38
!!! คุณช่วยวันของฉัน !!! ใช้แทน<div *ngIf="xxx"><div [hidden]="!xxx">
มาร์ค

1
สามารถยืนยันได้สิ่งนี้ได้ผลสำหรับฉันเช่นกัน ขอบคุณ zerg!
clo5ure

1
ขอบคุณมากนี่ทำให้ฉันเสียเวลามาก !!
themightylc

2
หรือตั้งค่าแหล่งข้อมูลเป็น ngAfterViewInit แทน ngOnInit
user3666653

1
นี่เป็นปัญหาที่ "ซ่อนอยู่" ส่วนใหญ่ที่อาจเกิดขึ้นขอบคุณสำหรับการแก้ปัญหา! เอกสารอาจเตือนเกี่ยวกับเรื่องนี้
Raycherr

37

ชื่อ matColumnDef และชื่อค่าจริง * matCellDef ควรเหมือนกัน

ตัวอย่าง:

<ng-container matColumnDef="oppNo">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Opportunity Number</th>
    <td mat-cell *matCellDef="let element">{{element.oppNo}}</td>
</ng-container>

ในกรณีของฉัน oppNo เหมือนกันสำหรับชื่อ matColumnDef และชื่อ * matCellDef และการเรียงลำดับทำงานได้ดี


น่าสนใจ. นั่นเป็นกรณีของฉันเช่นกัน แต่คุณรู้หรือไม่ว่าเหตุผลที่แท้จริงเบื้องหลังสิ่งนี้หรือนั่นคือ "ข้อบกพร่อง" บางอย่าง
ReturnTable

23

ฉันยังตีประเด็นนี้ เนื่องจากคุณต้องรอให้เด็กถูกกำหนดคุณต้องใช้และใช้AfterViewInitไม่ใช่ onInit

  ngAfterViewInit (){
    this.dataSource.sort = this.sort;
  }

สุดยอด! ขอบคุณ
Shashank Vivek

ฉันใช้ตารางที่มีการเรียงลำดับการกรองและการแบ่งหน้า คุณมีเงื่อนงำว่าทำไมต้องกำหนดเฉพาะการเรียงลำดับngAfterViewInit? ngOnInitส่วนที่เหลือได้รับการทำงานจาก แค่พยายามเข้าใจก็คงต้องขอบคุณคุณ
Nicolas M.

23

การเพิ่มการจัดเรียงในช่วงหมดเวลาเหมาะสำหรับฉัน

dataSource = new MatTableDataSource(this.articleService.getAllArticles());
setTimeout(() => {
  this.tableDataSource.sort = this.sort;
  this.tableDataSource.paginator = this.paginator;
});

หากคุณไม่ต้องการใช้ตะขอเกี่ยวข้อเท้า


1
แฮ็คโง่ แต่ใช้งานได้มีความคิดว่าทำไมมันถึงไม่ทำงานโดยไม่มีการหมดเวลา?
Ruben

ฉันใช้เวลานานเกินไปในการลองทำอย่างอื่นคิดว่าฉันจะบ้าไปแล้ว ทำงานอย่างมีเสน่ห์!
willpnw

4
เป็นวิธีที่ไม่ดีจริงๆ ทำงานได้เนื่องจากคุณปล่อยให้เวลาผ่านไปหลังจากการกำหนดค่าเริ่มต้นขององค์ประกอบเพื่อให้ dataSource ถูกสร้างขึ้นจากนั้นคุณจึงเพิ่มการเรียงลำดับและตัวแบ่งส่วน วิธีที่ดีที่สุดคือการย้าย datSource buidling ใน ngOnInit จากนั้นย้าย sort และ paginator assigments ใน AfterViewInit นั่นคือสิ่งที่ Lifecycle hooks มีไว้สำหรับ
Selam Getachew

14

ฉันใช้เวลาหลายชั่วโมงกับปัญหานี้ หลังจากอ่านหัวข้อต่างๆแล้วนี่คือขั้นตอนที่ฉันทำ

  1. ในฐานะที่เป็น@avern กล่าวถึงMatSortModuleคุณจะต้องนำเข้า
  2. ตรวจสอบให้แน่ใจว่าคุณไม่ได้ปิดตารางในไฟล์*ngIf. เปลี่ยนไป[hidden]เป็น@zerg แนะนำ (ฉันไม่เข้าใจว่าทำไม)

หวังว่านี่จะช่วยได้


ฉันเสียเวลาไปทั้งวันเพื่อค้นหาปัญหาและโง่ไม่แสดงข้อผิดพลาดใด ๆ
surekha shelake

11

วิธีแก้ปัญหาของฉันคือการแก้ไขหลายสิ่ง (โดยทั่วไปจะรวมโซลูชันส่วนใหญ่ในหน้านี้)

สิ่งที่ต้องตรวจสอบ:

  1. BrowserModule, MatTableModule, MatSortModule ควรนำเข้าโมดูลในไฟล์โมดูลรูท
  2. ตรวจสอบให้แน่ใจว่าได้ใช้ MatTableDatasourceคลาสและส่งอาร์เรย์ข้อมูลของคุณเป็นพารามิเตอร์
  3. ตรวจสอบให้แน่ใจว่าตารางของคุณไม่ได้ซ้อนอยู่ใน*ngIf=....คำสั่ง ใช้การดำเนินการตามเงื่อนไขอื่น ๆ แทน (ยังไม่เข้าใจว่าทำไม)


4

ฉันพบบล็อกเก่านี้ซึ่งช่วยให้ฉันใช้งานได้: https://www.jeffryhouser.com/index.cfm/2018/10/23/Five-Reasons-My-ngMaterial-Table-wont-sort

  1. อย่าลืมนำเข้า MatSortModule
  2. ระบุmatSortส่วนหัว
  3. อย่าลืมรวมแหล่งข้อมูลของคุณเป็นไฟล์ MatTableDataSource
    • นี่คือสิ่งที่ช่วยฉันจัดเรียง (เข้าใจไหมจัดเรียงออก) ในเทมเพลตฉันอ้างถึงอาร์เรย์โดยตรง ( <table mat-table [dataSource]="this.products" matSort>) แต่ฉันควรใช้วัตถุแหล่งข้อมูลที่ฉันเริ่มต้นในรหัส ( <table mat-table [dataSource]="this.dataSource" matSort>) แหล่งข้อมูลเริ่มต้นเช่นdataSource = new MatTableDataSource(this.products)
  4. บอกแหล่งข้อมูลเกี่ยวกับการจัดเรียงของคุณในngOnInit/ngAfterViewInit
  5. เขียนการเรียงลำดับของคุณเองหากคุณไม่ต้องการใช้ MatTableDataSource

3

สำหรับฉันการแทนที่ * ngIf ด้วยแอตทริบิวต์ [ซ่อน] สำหรับแท็ก mat-table ทำงานได้ จะโพสต์สิ่งนี้เป็นจุดบกพร่องในชุมชน Angular Material ได้อย่างไร


3

ฉันแก้ไขสิ่งนี้ในสถานการณ์ของฉันโดยตั้งชื่อข้อมูลตารางด้วยชื่อเดียวกับ * matColumnDef ตัวอย่างเช่น:

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

แทน

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

2

สาเหตุหนึ่งที่ MatSort อาจไม่ทำงานคือเมื่อมีการเพิ่มลงในแหล่งข้อมูล (เช่นthis.dataSource.sort = this.sort) ก่อนที่จะมีการกำหนด อาจมีสาเหตุหลายประการสำหรับสิ่งนี้:

  1. หากคุณเพิ่มการจัดเรียงใน ngOnInit ณ จุดนี้แม่แบบยังไม่แสดงผลดังนั้น MatSort ที่คุณได้รับ@ViewChild(MatSort, { static: true }) sort: MatSort;จึงไม่ได้กำหนดไว้และจะไม่ทำอะไรเลย วิธีแก้ไขสำหรับปัญหานี้คือย้ายthis.dataSource.sort = sortไปที่ ngAfterViewInit เมื่อ ngAfterViewInit ถูกเรียกว่าองค์ประกอบของคุณถูกแสดงผลและควรกำหนด MatSort

  2. เมื่อคุณใช้ * ngIf คือเทมเพลตของคุณบนองค์ประกอบตารางของคุณหรืออย่างใดอย่างหนึ่งหากเป็นองค์ประกอบหลักและสิ่งนี้ทำให้ * ngIf ไม่แสดงผลตารางของคุณในขณะที่คุณพยายามตั้งค่า MatSort ตัวอย่างเช่นหากคุณมี*ngIf="dataSource.data.length > 0"ในองค์ประกอบตารางของคุณ (เพื่อแสดงผลเฉพาะเมื่อมีข้อมูลอยู่) และคุณตั้งค่าthis.dataSource.sort = this.sortทันทีหลังจากที่คุณตั้งค่าthis.dataSource.dataด้วยข้อมูลของคุณ ยังไม่มีการแสดงผลมุมมองส่วนประกอบดังนั้น MatSort จะยังไม่ได้กำหนด

เพื่อให้ MatSort ทำงานและยังคงแสดงตารางของคุณตามเงื่อนไขคุณสามารถตัดสินใจแทนที่*ngIfด้วย[hidden]ตามที่ระบุไว้ในคำตอบอื่น ๆ อย่างไรก็ตามหากคุณต้องการเก็บคำสั่ง * ngIf ไว้คุณสามารถใช้วิธีแก้ไขปัญหาต่อไปนี้ โซลูชันนี้ใช้ได้กับ Angular 9 ฉันยังไม่ได้ทดสอบกับเวอร์ชันก่อนหน้าดังนั้นฉันจึงไม่แน่ใจว่าใช้ได้หรือไม่

ฉันพบโซลูชันนี้ที่นี่: https://github.com/angular/components/issues/10205

แทนที่จะใส่:

@ViewChild(MatSort) sort: MatSort;

ใช้ setter สำหรับ matSort ตัวตั้งค่านี้จะเริ่มทำงานเมื่อ matSort ในมุมมองของคุณเปลี่ยนไป (เช่นถูกกำหนดในครั้งแรก) จะไม่เริ่มทำงานเมื่อคุณเปลี่ยนการเรียงลำดับโดยคลิกที่ลูกศร สิ่งนี้จะมีลักษณะดังนี้:

@ViewChild(MatSort) set matSort(sort: MatSort) {
    this.dataSource.sort = sort;
}

หากคุณมีฟังก์ชั่นอื่น ๆ ที่ (โดยทางโปรแกรม) เปลี่ยนการเรียงลำดับฉันไม่แน่ใจว่าจะเริ่มทำงานอีกครั้งหรือไม่ฉันยังไม่ได้ทดสอบ หากคุณไม่แน่ใจว่าจะตั้งค่าเฉพาะการจัดเรียงหากไม่ได้กำหนดการจัดเรียงคุณสามารถดำเนินการดังนี้:

@ViewChild(MatSort) set matSort(sort: MatSort) {
    if (!this.dataSource.sort) {
        this.dataSource.sort = sort;
    }
}

Thankyou Emmy (& Abhijith-Nagaraja) :-) การใช้ฟังก์ชัน Set ในการเรียงลำดับทำให้การเรียงลำดับในองค์ประกอบกริดของฉันมีชีวิตขึ้นมา .. ในที่สุด :-)
Kieran Ryan

2

สำหรับใครที่สับสนเกี่ยวกับการตั้งชื่อเหล่านี้ที่ต้องเท่ากันฉันได้ทำการทดสอบ:

สิ่งนี้จะใช้งานได้ (ชื่อของคุณสมบัติเหมือนกับคอลัมน์ def):

<ng-container matColumnDef="version">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Version </th>
    <td mat-cell *matCellDef="let element"> {{element.version}} </td>
</ng-container>

displayedColumns: string[] = ['version']

สิ่งนี้จะไม่ทำงาน (ชื่อของคุณสมบัติไม่เหมือนกับคอลัมน์ def):

<ng-container matColumnDef="version2">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Version </th>
    <td mat-cell *matCellDef="let element"> {{element.version}} </td>
</ng-container>

displayedColumns: string[] = ['version2']

Fyi สิ่งนี้ยังใช้ไม่ได้ (ความยาวของคุณสมบัติ):

<ng-container matColumnDef="length">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Version </th>
    <td mat-cell *matCellDef="let element"> {{element.ids.length}} </td>
</ng-container>

displayedColumns: string[] = ['length']

และไม่ทำสิ่งนี้:

<ng-container matColumnDef="ids.length">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Version </th>
    <td mat-cell *matCellDef="let element"> {{element.ids.length}} </td>
</ng-container>

displayedColumns: string[] = ['ids.length']

ในกรณีของตัวเลือกที่สาม {{element.ids.length}} จะมีวิธีแก้ไขหรือไม่หากข้อมูลได้รับการจำลองแบบนั้นแล้ว
Paco Zevallos

1

หากตารางของคุณอยู่ใน * ngIf และคุณคิดว่ามันมีส่วนเกี่ยวข้องกับการที่มันไม่จัดเรียงตารางของคุณการระบุsortingDataAccessorฟังก์ชันของคุณเองอาจช่วยแก้ปัญหาได้เหมือนกับที่ฉันทำ ฉันมีโต๊ะของฉันอยู่ใน * ngIfs สองสามตัวและการเอาออกจาก * ngIfs เหล่านั้นไม่สมเหตุสมผล:

`ngAfterViewInit(): void {
        this.matchesDataSource.sort = this.sort;
        this.matchesDataSource.sortingDataAccessor = previewMatchSortingFn;
    }`

`export function previewMatchSortingFn(item: Match, header: string): string | number {
    switch (header) {
        case 'home':
            return item.homeTeam.name;
        case 'away':
            return item.awayTeam.name;
        case 'date':
            if (item.dateTime) {
                // this will return the number representation of the date
                return item.dateTime.valueOf();
            }
            return;
        default:
            break;
    }
}`

0

จริงๆแล้วชื่อ matColumnDef (เช่นชื่อคอลัมน์) และชื่อคุณสมบัติ Class / Interface ของคุณควรจะเท่ากันเพื่อให้ใช้งานได้

บางครั้งเราไม่สามารถเปลี่ยนชื่อคุณสมบัติคลาส / อินเทอร์เฟซของเราได้ในกรณีนั้นเราสามารถใช้การจัดเรียงแบบกำหนดเองได้ดังต่อไปนี้

let say your columns  as  ['id', 'name'] and 
your class/interface  as  ['userId', 'name']

หากเราทำการเรียงลำดับในคอลัมน์'id'มันจะไม่ทำงาน ลองใช้การจัดเรียงแบบกำหนดเอง

this.dataSource.sortingDataAccessor = (item,property)=>{

 // where item is your class/interface data
 // where property is your column name

       switch(property){
           case 'id' : return item.userId
           default: return item[property];
        }
}

0

หากคุณอ่านคำตอบทั้งหมดจนถึงตรงนี้และไม่มีอะไรช่วยคุณอาจมีปัญหาเดียวกันกับฉัน

ปัญหาคือMatTableDataSourceวัตถุของฉัน

dataSource = new MatTableDataSource<StbElement>(ELEMENT_DATA);

ถูกใช้ในไฟล์ html โดยไม่มีthis.

การเปลี่ยน:

<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">

ถึง:

<table mat-table [dataSource]="this.dataSource" matSort class="mat-elevation-z8">

แก้ไขปัญหา


0

ฉันพบคำตอบหลายข้อสำหรับคำถามนี้ แต่การนำไปใช้ทีละคำไม่ได้ให้ผลลัพธ์ใด ๆ กับฉัน ดังนั้นฉันจึงพยายามรวมคำตอบและได้ผล

ประการแรกฉันเพิ่มการจัดเรียง ViewChild ภายในอินเทอร์เฟซ NgAfterViewInit (ตอนแรกอยู่ในฟังก์ชันที่เรียกผ่าน NgOnInit

 ngAfterViewInit(){
    this.tableData.sort = this.sort;
  }

สำหรับขั้นตอนที่สองฉันเปลี่ยน * ngIf ภายในคอนเทนเนอร์เป็น [hidden] ฉันได้รับข้อผิดพลาดที่แจ้งว่าไม่ได้โหลดค่า แต่มันไม่ใช่เรื่องสำคัญที่ต้องกังวลจนถึงตอนนี้

ก่อน

<div class="mat-elevation-z0 container-fluid" *ngIf={some boolean resultant condition}>

หลังจาก

<div class="mat-elevation-z0 container-fluid" [hidden] = {negation of your boolean expression}>

psst .. คุณยังสามารถพิจารณาเพิ่มสปินเนอร์การโหลดในขณะที่ตารางของคุณกำลังโหลดผ่าน mat-footer ไปที่เหนือ bs ด้านบน

    <ng-container matColumnDef="loading">
                    <mat-footer-cell *matFooterCellDef colspan=6>
                        <div class="uploader-status">
                            <mat-spinner strokeWidth="25" [diameter]="100" title="Server Starting" ></mat-spinner>
                        </div>
                    </mat-footer-cell>
</ng-container>


<mat-footer-row *matFooterRowDef="['loading']" [ngStyle]="{'display': (this.candidateService.candidateRecords!=null) ? 'none':'block'}"></mat-footer-row>

-1

ดูว่าคุณมีข้อผิดพลาดเกี่ยวกับจาวาสคริปต์ในคอนโซลหรือไม่ อาจเป็นไปได้ว่ามีบางอย่างล้มเหลวก่อนที่การจัดเรียงของคุณจะเริ่มต้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.