MEANStack角表-排序和分页功能 [英] MEANStack Angular Table - Sorting and Pagination Functionalities

查看:114
本文介绍了MEANStack角表-排序和分页功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用MEANStack开发一个WebApp,目前正在Angular的前端上工作.我的应用程序仅读取SQL数据表,并以Angular Tables的形式在浏览器中显示它们.

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.

这是它的样子: 数据表显示MEANStack应用

很遗憾,排序功能不起作用.知道为什么吗?此外,鉴于我的表有点大,我如何实现左右滚动"功能?

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

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

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

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:

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:

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: ProcessTable[]; applicationsTables: ApplicationsTable[]; tableCount: number }>();

  constructor(private http: HttpClient, private router: Router) {}

  getProcessTables(tablesPerPage: number, currentPage: number) {
    const queryParams = `?pagesize=${tablesPerPage}&page=${currentPage}`;
    this.http
      .get<{ processTables: ProcessTable[]; applicationsTables: ApplicationsTable[]; maxTables: number }>(
        BACKEND_URL + queryParams
      )
      .pipe(
        map((tableData: { processTables: ProcessTable[]; applicationsTables: ApplicationsTable[]; maxTables: number }) => {
          return {
            processTables: tableData.processTables.processTables.map(table => {
              return {
                ProcessID: table.ProcessID
                ProcessName: table.ProcessName,
                PackageVersion: table.PackageVersion,
                RobotType: table.RobotType,
                PackagePath: table.PackagePath,
                CreationTime: table.CreationTime,
                Status: table.Status
              };
            }),
             applicationsTables: tableData.applicationsTables.applicationsTables.map(table => {
              return {
                ProcessName: table.ProcessName,
                PackageVersion: table.PackageVersion,
                WorkflowsBelongingToProcess: table.WorkflowsBelongingToProcess,
                ApplicationsBelongingToWorkflow: table.ApplicationsBelongingToWorkflow
              };
            }),
            maxTables: tableData.maxTables
          };
        })
      )
      .subscribe(transformedTablesData => {
        this.processTables = transformedTablesData.processTables;
        this.applicationsTables = transformedTablesData.applicationsTables;
        this.tablesUpdated.next({
          processTables: [...this.processTables],
          applicationsTables: [...this.applicationsTables],
          tableCount: transformedTablesData.maxTables
        });
      });
  }

  getTableUpdateListener() {
    return this.tablesUpdated.asObservable();
  }
}

Tables \ model.ts:

Tables\model.ts:

export interface Table {
  ProcessID: string;
  ProcessName: string;
  PackageVersion: string;
  RobotType: string;
  PackagePath: string;
  CreationTime: string;
  Status: string;
}

export interface ApplicationsTable {
  ProcessName: string;
  PackageVersion: string;
  WorkflowsBelongingToProcess: string;
  ApplicationsBelongingToWorkflow: string;
}

后端\控制器\ tables.js:

Backend\controllers\tables.js:

const sequelize = require("../sequelize");

const getProcessTables = (req, res) => {
  return sequelize
    .query("SELECT * FROM dbo.Process", { type: sequelize.QueryTypes.SELECT })
    .then(fetchedtables => {
      return {
        message: "Process table fetched from the server",
        processTables: fetchedtables,
        maxProcessTables: fetchedtables.length
      };
    });
};

const getApplicationsTables = (req, res) => {
  return sequelize
    .query("SELECT * FROM dbo.Applications", {
      type: sequelize.QueryTypes.SELECT
    })
    .then(fetchedtables => {
      return {
        message: "Applications Table fetched from the server",
        applicationsTables: fetchedtables,
        maxApplicationsTables: fetchedtables.length
      };
    });
};

exports.getTables = (req, res) => {
  return Promise.all([
    getApplicationsTables(req, res),
    getProcessTables(req, res)
  ]).then(tables => {
    res.status(200).json({
      applicationsTables: tables[0],
      processTables: tables[1]
    });
  });
};

后端\ routes \ tables.js:

Backend\routes\tables.js:

const express = require("express");

const TableController = require("../controllers/tables")

const router = express.Router({ mergeParams: true });

router.get("", TableController.getTables);

module.exports = router;

我该如何解决? 非常感谢 根纳罗(Gennaro)

How can I fix it? Many Thanks Gennaro

推荐答案

我相信您正在使用Angular Material7.x.x.我们可以将数据源分配给MatTableSource()吗?它具有更丰富的属性,可以封装排序,分页,...

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,...

现在您正在使用任何processTables对象实例.排序或分页无法链接.请使用以下示例 https://stackblitz.com/angular/pakljarjylj?file = app%2Ftable-sorting-example.ts

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:

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
}

这篇关于MEANStack角表-排序和分页功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆