Angular Material2 md-table不会被渲染

时间:2017-07-10 08:49:37

标签: angular rendering angular-material2

我目前正在实施angular-material2的新md表。

它确实有效,包括过滤器。但是当我重新加载桌子所在的页面时,表格不会显示出来。当我点击按钮或过滤器输入时,它会被渲染。

以下是代码:

<md-toolbar color="primary" class="mat-elevation-z8">
    Projects
    <span class="fill-remaining-space"></span>
    <button md-button (click)="openProjectDialog()">
        <md-icon>add</md-icon>
    </button>
</md-toolbar>
<div class="inner-sidenav-content">
    <div class="mat-elevation-z5">
        <div class="table-header">
            <md-input-container floatPlaceholder="never">
                <input mdInput #filter placeholder="Filter projects">
            </md-input-container>
        </div>

        <md-table #table [dataSource]="dataSource">
            <!-- ID column -->
            <ng-container cdkColumnDef="id">
                <md-header-cell *cdkHeaderCellDef>ID</md-header-cell>
                <md-cell *cdkCellDef="let row">{{row.id}}</md-cell>
            </ng-container>

            <!-- Project number column -->
            <ng-container cdkColumnDef="number">
                <md-header-cell *cdkHeaderCellDef>Number</md-header-cell>
                <md-cell *cdkCellDef="let row">{{row.number}}</md-cell>
            </ng-container>

            <!-- Project name column -->
            <ng-container cdkColumnDef="name">
                <md-header-cell *cdkHeaderCellDef>Name</md-header-cell>
                <md-cell *cdkCellDef="let row">{{row.name}}</md-cell>
            </ng-container>

            <md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
            <md-row *cdkRowDef="let row; columns: displayedColumns;"></md-row>
        </md-table>
    </div>
</div>

打字稿:

import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {Project} from '../../models/project';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {DataSource} from '@angular/cdk';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/observable/merge';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/observable/fromEvent';
import {MdDialog} from '@angular/material';
import {ProjectDialogComponent} from '../../components/project-modal/project-dialog.component';

@Component({
    selector: 'wtc-projects',
    templateUrl: './projects.component.html',
    styleUrls: ['./projects.component.scss']
})
export class ProjectsComponent implements OnInit {
    displayedColumns = ['id', 'number', 'name'];
    exampleDatabase = new ExampleProjectDatabase();
    dataSource: ExampleProjectSource | null;

    @ViewChild('filter') filter: ElementRef;

    constructor(public dialog: MdDialog) {
    }

    ngOnInit() {
        this.dataSource = new ExampleProjectSource(this.exampleDatabase);

        Observable.fromEvent(this.filter.nativeElement, 'keyup')
            .debounceTime(150)
            .distinctUntilChanged()
            .subscribe(() => {
                if (!this.dataSource) {
                    return;
                }
                this.dataSource.filter = this.filter.nativeElement.value;
            });
    }

    openProjectDialog(): void {
        const newProject = new Project();
        const dialogRef = this.dialog.open(ProjectDialogComponent, {
            data: newProject
        });
        dialogRef.afterClosed().subscribe(result => {
            if (result) {
                this.exampleDatabase.addProject(result);
            }
        });
    }

}

export class ExampleProjectDatabase {
    // Stream that emits whenever the data has been modified
    dataChange: BehaviorSubject<Project[]> = new BehaviorSubject<Project[]>([]);

    get data(): Project[] {
        return this.dataChange.value;
    }

    constructor() {
        // Fill up the database
        this.addProject(new Project(1, '52342', 'Landing Pages'));
        this.addProject(new Project(2, '1234', 'Maintenance Interface'));
        this.addProject(new Project(3, '6576', 'Mobile Time Tracking app'));
        this.addProject(new Project(4, '52342', 'TYPO3 Website'));
    }

    // Adds new project to the database
    addProject(project: Project) {
        const copiedData = this.data.slice();
        copiedData.push(project);
        this.dataChange.next(copiedData);
    }
}

export class ExampleProjectSource extends DataSource<any> {
    _filterChange = new BehaviorSubject('');

    get filter(): string {
        return this._filterChange.value;
    }

    set filter(filter: string) {
        this._filterChange.next(filter);
    }

    constructor(private _exampleDatabase: ExampleProjectDatabase) {
        super();
    }

    connect(): Observable<Project[]> {
        const displayDataChanges = [
            this._exampleDatabase.dataChange,
            this._filterChange,
        ];

        return Observable.merge(...displayDataChanges).map(() => {
            return this._exampleDatabase.data.slice().filter((item: Project) => {
                const searchStr = (item.number + item.name).toLowerCase();
                return searchStr.indexOf(this.filter.toLowerCase()) !== -1;
            });
        });
    }

    disconnect() {
    }
}

路由:

{
    path: 'projects',
    component: ProjectsComponent
},

当我重新加载页面时: enter image description here

当我在重新加载后单击某些内容时它应该如何: enter image description here

有人知道问题出在哪里吗?提前谢谢!

1 个答案:

答案 0 :(得分:0)

如果你的代码有问题,我就错过了。您可能需要open an issue here

作为解决方法,我会尝试在ngAfterViewInit lifecycle hook

中手动触发检测
import {ChangeDetectorRef} from '@angular/core';
...
export class ProjectsComponent implements OnInit, AfterViewInit {

  constructor(public dialog: MdDialog, private detector:ChangeDetectorRef) {
  }

  // add this
  ngAfterViewInit(){
    this.detector.detectChanges();
  }
}