Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
366 views
in Technique[技术] by (71.8m points)

sql - MEANStack Angular Table - Sorting and Pagination Functionalities

I'm developing a WebApp with MEANStack, currently working on the Front End with Angular. My App simply reads SQL Data Tables and displays them on a browser in the form of Angular Tables.

Here's how it looks like: Data Table Display MEANStack App

Unfortunately the Sort functionality does not work. Any idea why? Furthermore, how can I implement the "scroll left and right" functionality, given that my tables are a bit large?

Here's my code (Please do not hesitate to ask for more code):

tables-list.component.html

<mat-spinner *ngIf="isLoading"></mat-spinner>
  <h1 class="mat-body-2">Process List &nbsp; </h1>

  <mat-accordion multi="true" *ngIf="userIsAuthenticated && !isLoading">
    <mat-expansion-panel>
      <mat-expansion-panel-header>
        Process List
      </mat-expansion-panel-header>
  <table mat-table [dataSource]="processTables" matSort class="mat-elevation-z8" *ngIf="userIsAuthenticated">

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

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

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

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

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

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

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

      <!-- Header and Row Declarations -->
      <tr mat-header-row *matHeaderRowDef="displayedprocessTablesColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedprocessTablesColumns;"></tr>
    </table>
  </mat-expansion-panel>
</mat-accordion>


    <br> <h1 class="mat-body-2">Applications List &nbsp; </h1>

    <mat-accordion multi="true" *ngIf="userIsAuthenticated && !isLoading">
      <mat-expansion-panel>
        <mat-expansion-panel-header>
          Applications List
        </mat-expansion-panel-header>
    <table mat-table [dataSource]="applicationsTables" matSort class="mat-elevation-z8" *ngIf="userIsAuthenticated">

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

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

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

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

        <!-- Header and Row Declarations -->
        <tr mat-header-row *matHeaderRowDef="displayedApplicationsTablesColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedApplicationsTablesColumns;"></tr>
      </table>
    </mat-expansion-panel>
  </mat-accordion>

tables.module.ts

import { NgModule } from "@angular/core";
import { ReactiveFormsModule } from "@angular/forms";
import { CommonModule } from "@angular/common";
import { RouterModule } from "@angular/router";

import { TableListComponent } from "./tables-list.component";
import { AngularMaterialModule } from "../angular-material.module";

@NgModule({
  declarations: [TableListComponent],
  imports: [
    CommonModule,
    ReactiveFormsModule,
    AngularMaterialModule,
    RouterModule
  ]
})
export class TablesModule {}

angular-material.module.ts

import { NgModule } from "@angular/core";
import {
  MatInputModule,
  MatCardModule,
  MatButtonModule,
  MatToolbarModule,
  MatExpansionModule,
  MatProgressSpinnerModule,
  MatPaginatorModule,
  MatDialogModule,
  MatSelectModule,
  MatListModule,
  MatIconModule,
  MatTableModule,
  MatSortModule,
  MatTabsModule,
  MatAutocompleteModule,
  MatBadgeModule,
  MatBottomSheetModule,
  MatButtonToggleModule,
  MatCheckboxModule,
  MatChipsModule,
  MatStepperModule,
  MatDatepickerModule,
  MatGridListModule,
  MatDividerModule,
  MatMenuModule,
  MatNativeDateModule,
  MatProgressBarModule,
  MatRadioModule,
  MatRippleModule,
} from "@angular/material";
import { CdkTableModule } from "@angular/cdk/table";
import { CdkTreeModule } from "@angular/cdk/tree";

@NgModule({
  exports: [
    MatInputModule,
    MatCardModule,
    MatButtonModule,
    MatToolbarModule,
    MatExpansionModule,
    MatProgressSpinnerModule,
    MatPaginatorModule,
    MatDialogModule,
    MatSelectModule,
    MatListModule,
    MatIconModule,
    MatTableModule,
    MatSortModule,
    MatTabsModule,
    CdkTableModule,
    CdkTreeModule,
    MatAutocompleteModule,
    MatBadgeModule,
    MatBottomSheetModule,
    MatButtonToggleModule,
    MatCheckboxModule,
    MatChipsModule,
    MatStepperModule,
    MatDatepickerModule,
    MatDividerModule,
    MatGridListModule,
    MatMenuModule,
    MatNativeDateModule,
    MatProgressBarModule,
    MatRadioModule,
    MatRippleModule,
  ]
})
export class AngularMaterialModule {}

tables-list.component.ts:

    import { Component, OnInit, OnDestroy, ViewChild } from "@angular/core";
    import { ProcessTable, ApplicationsTable } from "./tables.model";
    import { PageEvent, MatTableDataSource, MatSort } from "@angular/material";

    import { Subscription } from "rxjs";
    import { TablesService } from "./tables.service";
    import { AuthService } from "../auth/auth.service";

    @Component({
      // We load the component via routing and therefore we do not need a selector
      selector: "app-tables",
      templateUrl: "./tables-list.component.html",
      styleUrls: ["./tables-list.component.css"]
    }) // Turn class into component by adding @Component Decorator

    export class TableListComponent implements OnInit, OnDestroy {
      processTables: ProcessTable[] = [];
      applicationsTables: ApplicationsTable[] = [];
      isLoading = false;
      totalTables = 0;
      tablesPerPage = 5;
      currentPage = 1;
          pageSizeOptions = [1, 2, 5, 10];

  dataSource = new MatTableDataSource(this.processTables);
  @ViewChild(MatSort) sort: MatSort;

      displayedprocessTablesColumns: string[] = [
    "ProcessID",
    "ProcessName",
    "PackageVersion",
    "RobotType",
    "PackagePath",
    "CreationTime",
    "Status"
  ];
  displayedApplicationsTablesColumns: string[] = [
    "ProcessName",
    "PackageVersion",
    "WorkflowsBelongingToProcess",
    "ApplicationsBelongingToWorkflow"
  ];
      userIsAuthenticated = false;
      userId: string;
      isAdmin: boolean;

      private tablesSub: Subscription;
      private authStatusSub: Subscription;

      constructor(
        public tablesService: TablesService,
        private authService: AuthService
      ) {}



    ngOnInit() {
            this.isLoading = true;
this.dataSource.sort = this.sort;
            this.tablesService.getProcessTables(this.tablesPerPage, this.currentPage);
            this.userId = this.authService.getUserId();
            this.tablesSub = this.tablesService
              .getTableUpdateListener()
              .subscribe((tableData: { processTables: ProcessTable[]; applicationsTables: ApplicationsTable[]; tableCount: number }) => {
                this.isLoading = false;
                this.totalTables = tableData.tableCount;
                this.processTables = tableData.processTables;
                this.applicationsTables = tableData.applicationsTables;
              });
            this.userIsAuthenticated = this.authService.getIsAuth();
            // console.log("Is authenticated: " + this.userIsAuthenticated);
            this.authStatusSub = this.authService
              .getAuthStatusListener()
              .subscribe(isAuthenticated => {
                this.userIsAuthenticated = isAuthenticated;
              });
          }

          onLogout() {
            this.authService.logout();
          }

          ngOnDestroy() {
            this.tablesSub.unsubscribe();
            this.authStatusSub.unsubscribe();
          }
        }

Tables.service.ts:

import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Subject } from "rxjs";
import { map } from "rxjs/operators";
import { Router } from "@angular/router";

import { environment } from "../../environments/environment";
import { ProcessTable, ApplicationsTable } from "./tables.model";

const BACKEND_URL = environment.apiUrl + "/tables/";

@Injectable({ providedIn: "root" })
export class TablesService {
  private processTables: ProcessTable[] = [];
  private applicationsTables: ApplicationsTable[] = [];
  private tablesUpdated = new Subject<{ processTables: ProcessT

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I believe you are using Angular Material 7.x.x. Can we assign datasource to MatTableSource()? It has more rich properties to encapsulate the sorting, pagination,...

Now that you are using any instance of processTables object. Sorting or pagination cannot be linked. Please use this example https://stackblitz.com/angular/pakljarjylj?file=app%2Ftable-sorting-example.ts

tables-list.component.ts:

import { Component, OnInit, OnDestroy } from "@angular/core";
import { ProcessTable, ApplicationsTable } from "./tables.model";
import { PageEvent } from "@angular/material";

import { Subscription } from "rxjs";
import { TablesService } from "./tables.service";
import { AuthService } from "../auth/auth.service";

@Component({
  // We load the component via routing and therefore we do not need a selector
  selector: "app-tables",
  templateUrl: "./tables-list.component.html",
  styleUrls: ["./tables-list.component.css"]
}) // Turn class into component by adding @Component Decorator

export class TableListComponent implements OnInit, OnDestroy {
  // ....other lines
  dataSource = new MatTableDataSource(processTables);
  // ....other lines
  @ViewChild(MatSort) sort: MatSort;
  // ....other lines
  ngOnInit() {
    this.dataSource.sort = this.sort;
  }
  // ....other lines
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...