代码之家  ›  专栏  ›  技术社区  ›  Lushmoney

角度6-通过材料扩展面板内的材料表循环

  •  2
  • Lushmoney  · 技术社区  · 6 年前

    我有个问题我有点迷路了。我有一个材料扩展面板,它的标题是通过循环通过一个变量来填充的,这个变量包含我拥有的数据,这是一个对象数组-在这个对象数组中,有一个键的值是扩展面板标题。还有一个键,它的值是另一个对象数组,我想循环通过它来填充每个扩展面板内的材质表。

    这是我到目前为止得到的。。。

    export const titles = [
        {
            title: 'First Title',
            titleId: 'firstTitle',
            info: [
                { name: 'Info One', code: 'infoOne' },
                { name: 'Info Two', code: 'infoTwo' },
                { name: 'Info Three', code: 'infoThree' },
                { name: 'Info Four', code: 'infoFour' }
            ]
        },
        {
            title: 'Second Title',
            titleId: 'secondTitle',
            info: [
                { name: 'Package', code: 'package' },
                { name: 'Package Two', code: 'packageTwo' } 
            ]
        },
        {
            title: 'Third Title',
            titleId: 'thirdTitle',
            info: [
                { name: 'Widget One', code: 'widgetOne' },
                { name: 'Widget Two', code: 'widgetTwo' },
                { name: 'Widget Three', code: 'widgetThree' },
                { name: 'Widget Four', code: 'widgetFour' }
            ]
        }
    ]
    

    标题.component.ts:

    import {Component} from '@angular/core';
    import {SelectionModel} from '@angular/cdk/collections';
    import {MatTableDataSource} from '@angular/material';
    import {titles} from './titleGroups';
    
    export interface TitleNames {
        name: string;
    }
    
    const TITLES: any[] = titles;
    
    let TITLE_NAMES;
    for(let i = 0; i < TITLES.length; i++)
        for(let j = 0; j < TITLES[i].info.length; j++)
            TITLE_NAMES = TITLES[i].info;
    
    @Component({
        selector: 'aa-titles',
        templateUrl: './aa-titles.component.html',
        styleUrls: ['./aa-titles.component.scss']
    })
    
    export class TitlesComponent {
        displayedColumns: string[] = ['select', 'name'];
        dataSource = new MatTableDataSource<TitleNames>(TITLE_NAMES);
        selection = new SelectionModel<TitleNames>(true, []);
        titleData: any;
    
        constructor() {
            this.titleData = TITLES;
        }
    
        isAllSelected() {
            const numSelected = this.selection.selected.length;
            const numRows = this.dataSource.data.length;
    
            return numSelected === numRows;
        }
    
        masterToggle() {
            this.isAllSelected() ?
                this.selection.clear() :
                this.dataSource.data.forEach(row => this.selection.select(row));
        }
    }
    

    <mat-accordion multi="true">
        <mat-expansion-panel *ngFor="let item of titleData">
            <mat-expansion-panel-header>{{item.title}}</mat-expansion-panel-header>
    
            <table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
                <!-- Checkbox Column -->
                <ng-container matColumnDef="select">
                    <th mat-header-cell *matHeaderCellDef>
                        <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>
    
                <!-- Name Column -->
                <ng-container matColumnDef="name">
                    <th mat-header-cell *matHeaderCellDef> Name </th>
                    <td mat-cell *matCellDef="let element"> {{element.name}} </td>
                </ng-container>
    
                <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
                <tr mat-row *matRowDef="let row; columns: displayedColumns;"
                    (click)="selection.toggle(row)">
                </tr>
            </table>
        </mat-expansion-panel>
    </mat-accordion>
    

    现在的情况是,在每个扩展面板下,它只显示标题的最后一个元素的数据 在每个扩展面板下面。

    我想让相应的扩展面板显示正确的数据

    显示表格的第一个标题扩展面板,显示:

    Info One

    Info Two

    Info Three

    Info Four

    显示表格的第二个标题扩展面板,显示:

    Package

    Package Two

    等等。我不知道如何做到这一点-任何帮助将不胜感激,谢谢!

    1 回复  |  直到 6 年前
        1
  •  4
  •   Burnee    6 年前

    你应该定义分离 dataSource -s和 selectionModel -每一张桌子的尺寸: 例如,您可以在 constructor

    this.titlesForIterate = titles.map(item => { 
        // I'm not doing it here, but you can also deep clone the item object first 
        item.dataSource = new MatTableDataSource<WidgetNames>(item.info);
        item.selectionModel = new SelectionModel<TitleNames>(true, []);
        return item;
    };
    

    titlesForIterate *ngFor 扩展面板。

    <mat-expansion-panel *ngFor="let item of titlesForIterate">
    

    数据源 选择模型

    <table mat-table [dataSource]="item.dataSource" class="mat-elevation-z8">
    
        ...
                    <mat-checkbox (change)="$event ? masterToggle() : null"
                                  [checked]="item.selection.hasValue() && isAllSelected(item)"
                                  [indeterminate]="item.selection.hasValue() && !isAllSelected(item)">
                    </mat-checkbox>
        ...
    

    笔记 :不要忘记重构 isAllSelected 方法接收父对象作为参数。