简体   繁体   中英

Selected row checkbox not showing With two NG-Container elements using Material Data Table (Angular 7)

I have a dynamic data table build using Angular Material where I am using an API to supply the table with data currently.

I want to use add a checkbox column to select a specific row, and/or multiple rows, but I'm having an issue with showing the checkbox row in order to make a selection.

Right now my row of checkboxes is not appearing at all. the first ng-container column is not showing

and I'm not sure what's the issue?

I'm using Angular 7 with Angular Material

view.component.html

 <table mat-table [dataSource]="fetchedData" matSort matSortActive="{{defaultSortCol}}" matSortDirection="asc">

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

    <ng-container [matColumnDef]="column.columnId" *ngFor="let column of viewData.ColumnObjects">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>
        {{ column.propertyName }}
      </th>
      <td mat-cell *matCellDef="let action">{{ action[column.columnId] }}</td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="viewData.ColumnIds; sticky: true"></tr>
    <tr mat-row *matRowDef="let row; columns: viewData.ColumnIds"></tr>
  </table>

view.component.ts

    @Component({
        templateUrl: 'viewpage.component.html'
    })
    export class ViewpageComponent implements AfterViewInit, OnInit, OnDestroy {

        viewData: any;
        viewName: string;
        viewTag: number;
        fetchedData: any;
        dataSource: ViewData

Source;
    pageSizeOptions: number[] = [10, 20, 50];

    defaultSortCol = "1";

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

    selection = new SelectionModel<TableRow>(true, []);


    navSub: any;

    constructor(private actionService: ActionService, private route: ActivatedRoute, private router: Router) { }

    ngOnInit() {
        // Init the component the first time it is navigated to.
        this.initData();
        // Subscribe to the router, so that any new navigation to this component loads new data.
        this.navSub = this.router.events.subscribe((e: any) => {
            if(e instanceof NavigationEnd){
                this.initData();
            }
        });
    }

    initData(){
        this.viewTag = +this.route.snapshot.paramMap.get("tag");
        this.dataSource = new ViewDataSource(this.actionService);

        // Load the View from the DataSource with default params
        this.dataSource.loadView(this.viewTag, 0, 10, this.defaultSortCol, "asc");

        // Subscribe to the View in the DataSource
        this.dataSource.view.subscribe(x => {
            if (x.ActionName) {
                this.viewName = x.ActionName;
                this.viewData = x;
                this.fetchedData = this.viewData.TableData;
                console.log(`View Data ` + JSON.stringify(this.viewData.ViewData.DbrAction));
                // this.viewData = ['select'].concat(this.viewData);
            }
        });
    }

    ngAfterViewInit() {
        // After sorting, jump back to first page of newly sorted data.
        this.sort.sortChange.subscribe(
            () => {
                this.paginator.pageIndex = 0
            });
        // Sort changes and pagination events should reload the page.
        merge(this.sort.sortChange, this.paginator.page)
            .pipe(
                tap(() => this.loadPage())
             ).subscribe();

    }

    loadPage() {
        this.dataSource.loadView(
            this.viewTag,
            //'',
            this.paginator.pageIndex,
            this.paginator.pageSize,
            this.sort.active,
            this.sort.direction);

    }

Your table try's to use viewdata before it is initial set, in fact viewData is undefined.

Thats why viewData.ColumnObjects throws an TypeError .

Try to use ? check eg viewData?.ColumnObjects or guard your table with *ngIf="viewData"

...
 <ng-container [matColumnDef]="column.columnId" *ngFor="let column of viewData?.ColumnObjects">
...

You mentioned a 'row' of checkboxes a few times, but it looks like you're trying to add a column of checkboxes, which makes sense given your requirement of selecting items in the table.

Does viewData.ColumnIds have 'select' in it? If not, that's your problem. The material table doesn't render every matColumnDef you give it, it only renders the matColumnDefs that have matching names in the 'columns' array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM