材料2表:查看不更新复选框

时间:2018-01-25 18:23:30

标签: angular angular-material2

当我在桌面上使用分页时,视图不会保留在先前页面上进行的复选框(选择)更改。我假设我需要在ngAfterViewInit()中添加一些内容,类似于paginator和sort。我尝试添加子视图和其他一些更改,但我无法弄清楚。

修改 我记录了一些东西,看起来选择模型正确更新,问题严格基于视图。

app.component.ts

import {Component, AfterViewInit, ViewChild} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {MatPaginator, MatSort, MatTableDataSource} from '@angular/material';
import {Observable} from 'rxjs/Observable';
import {merge} from 'rxjs/observable/merge';
import {of as observableOf} from 'rxjs/observable/of';
import {catchError} from 'rxjs/operators/catchError';
import {map} from 'rxjs/operators/map';
import {startWith} from 'rxjs/operators/startWith';
import {switchMap} from 'rxjs/operators/switchMap';
import {SelectionModel} from '@angular/cdk/collections';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit{
  displayedColumns = ['select','id', 'name', 'progress', 'color'];
  exampleDatabase: ExampleHttpDao | null;
  dataSource = new MatTableDataSource();
  selection = new SelectionModel<UserData>(true, []);

  resultsLength = 0;
  isLoadingResults = false;
  isRateLimitReached = false;

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;


  constructor(private http: HttpClient) {}

  ngAfterViewInit() {

    this.exampleDatabase = new ExampleHttpDao(this.http);

    // If the user changes the sort order, reset back to the first page.
    this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);

    merge(this.sort.sortChange, this.paginator.page)
      .pipe(
        startWith({}),
        switchMap(() => {
          this.isLoadingResults = true;
          return this.exampleDatabase!.getRepoIssues(
            this.sort.active, this.sort.direction, this.paginator.pageIndex);
        }),
        map(data => {
          // Flip flag to show that loading has finished.
          this.isLoadingResults = false;
          this.isRateLimitReached = false;
          this.resultsLength = data.total_count;

          return data.data;
        }),
        catchError(() => {
          this.isLoadingResults = false;
          // Catch if the GitHub API has reached its rate limit. Return empty data.
          this.isRateLimitReached = true;
          return observableOf([]);
        })
      ).subscribe(data => this.dataSource.data = data);

     this.dataSource.paginator = this.paginator;
     this.dataSource.sort = this.sort;
  }

  applyFilter(filterValue: string) {
    filterValue = filterValue.trim(); // Remove whitespace
    filterValue = filterValue.toLowerCase(); // Datasource defaults to lowercase matches
    this.dataSource.filter = filterValue;
  }

    /** Whether the number of selected elements matches the total number of rows. */
    isAllSelected() {
      const numSelected = this.selection.selected.length;
      const numRows = this.dataSource.data.length;
      return numSelected === numRows;
    }

    /** Selects all rows if they are not all selected; otherwise clear selection. */
    masterToggle() {
      this.isAllSelected() ?
          this.selection.clear() :
          this.dataSource.data.forEach(row => this.selection.select(row));
          this.dataSource.data.forEach(row => console.log());

    }
}

export interface UserDataApi {
  data: UserData[];
  total_count: number;
}

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 ExampleHttpDao {
  constructor(private http: HttpClient) {}

  getRepoIssues(sort: string, order: string, page: number): Observable<UserDataApi> {
    const requestUrl = './assets/data.json';

    return this.http.get<UserDataApi>(requestUrl);
  }
}  

app.component.html

<div class="example-header">
  <mat-form-field>
    <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
  </mat-form-field>
</div>

<mat-table #table [dataSource]="dataSource" class="example-table" matSort matSortActive="created" matSortDisableClear matSortDirection="asc">

  <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->

  <!-- Checkbox Column -->
  <ng-container matColumnDef="select">
    <mat-header-cell *matHeaderCellDef>
      <mat-checkbox (change)="$event ? masterToggle() : null" [checked]="selection.hasValue() && isAllSelected()" [indeterminate]="selection.hasValue() && !isAllSelected()">
      </mat-checkbox>
    </mat-header-cell>
    <mat-cell *matCellDef="let row">
      <mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? selection.toggle(row) : null" [checked]="selection.isSelected(row)">
      </mat-checkbox>
    </mat-cell>
  </ng-container>

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

  <!-- Title 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>

  <!-- State 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>

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


  <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
  <mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selection.toggle(row)">
    </mat-row>>
</mat-table>


<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>

1 个答案:

答案 0 :(得分:0)

在这种情况下我会使用ngModel,因为它也可以将复选框状态绑定到布尔值,并且在您通过材质表分页时应保持状态...

     <mat-checkbox [(ngModel)]="selection.hasValue() && isAllSelected()" 
                   [(indeterminate)]="selection.hasValue() && !isAllSelected()">
     </mat-checkbox>

如果这可以解决您的分页问题,​​请告诉我,为我工作。

编辑回答你的评论:将FormsModule添加到模块:

...
import { FormsModule } from '@angular/forms';

@NgModule({
  imports: [
    ...
    FormsModule
  ],

在你的组件中:

import {FormsModule} from '@angular/forms';