【问题标题】:covalent, td-data-table provide different color for odd/even rowscovalent, td-data-table 为奇数/偶数行提供不同的颜色
【发布时间】:2021-01-02 18:51:36
【问题描述】:

我正在使用共价来实现 augular 的表格。

vrp-table-component html 像这样:

    <span *ngIf="selectedRows?.length && selectable" class="push-left-sm">
        <span class="md-body-1">{{selectedRows?.length}} item(s) selected
            <span *ngFor="let a of selectActions">
                <button *ngIf="a.haspermission" mat-icon-button color='warn' [matTooltip]=" a.tooltip||a.label"
                    (click)="(a.click(selectedRows)) ? undefined: (cancelSelection())">
                    <mat-icon>{{a.icon}}</mat-icon>
                </button>
            </span>

            <button mat-icon-button matTooltip="Cancel selection" (click)="cancelSelection()">
                <mat-icon>close</mat-icon>
            </button>
        </span>
    </span>

    <ng-template [ngForOf]='tableActions' ngFor let-b>
        <button mat-button color="accent" *ngIf='b.menuTemplateRef && b.haspermission'
            [matMenuTriggerFor]="b.menuTemplateRef()">
            <mat-icon *ngIf='b.icon'>{{b.icon}}</mat-icon>{{b.label||''}}
        </button>

        <button mat-icon-button *ngIf='!b.menuTemplateRef && b.haspermission' [matTooltip]='b.tooltip || b.label'
            (click)='b.click()'>
            <mat-icon *ngIf='b.icon'>{{b.icon}}</mat-icon>{{b.label||''}}
        </button>
    </ng-template>

    <button mat-icon-button matTooltip='Select Columns' (click)='filterColumns()' *ngIf='showSelectColumns'>
        <mat-icon>filter_list</mat-icon>
    </button>
</div>

<mat-divider></mat-divider>

<td-data-table #dataTable [data]="filteredData" [columns]="columns" [selectable]="selectable"
    [clickable]="clickable" [multiple]="multiple" [sortable]="sortable" [sortBy]="sortBy" [(ngModel)]="selectedRows"
    [sortOrder]="sortOrder" (sortChange)="onSort($event)" (rowClick)='editRow.emit($event.row)'
    (selectAll)="onSelectAny()" (rowSelect)="onSelectAny()" [style.height.px]="dataTable.hasData?tableHeight:50"
    [style.min-width]="dataTable.hasData?(columns.length * minWidthFactor + 'px'):'auto'">

    <ng-template tdDataTableTemplate="_itemActions" let-value="value" let-row="row" let-column="column">
        <span *ngFor="let a of itemActions">
            <button mat-icon-button *ngIf="a.haspermission" (click)="a.click(row)"
                [matTooltip]='a.tooltip || a.label'>
                <mat-icon>{{a.icon}}</mat-icon>
            </button>
        </span>

        <span *ngIf='itemMenu && itemMenu.length > 0'>
            <button mat-icon-button [matMenuTriggerFor]="menuDetail">
                <mat-icon>more_vert</mat-icon>
            </button>

            <mat-menu [overlapTrigger]="false" #menuDetail="matMenu">
                <span *ngFor="let a of itemMenu">
                    <a mat-menu-item (click)="a.click(row)" *ngIf="a.haspermission">
                        <mat-icon *ngIf='a.icon'>{{a.icon}}</mat-icon>{{a.label}}
                    </a>
                </span>
            </mat-menu>
        </span>
    </ng-template>

    <ng-template tdDataTableTemplate="_error" let-value="value" let-row="row" let-column="column">
        <div layout='column'>
            <span *ngFor='let i of value'><strong>{{i[0]}}:</strong> {{i[1]}} </span>
        </div>
    </ng-template>
</td-data-table>

<div *ngIf="filteredData && filteredData.length===0" layout="row" layout-align="center center">
    <h3>No data to display.</h3>
</div>

和这样的 vrp-table-component.ts :

private _customFilteredData: any[];

// placeholders for the callbacks which are later provided by the Control Value Accessor
private _onTouchedCallback: () => void = noOp;
private _onChangeCallback: (_: any) => void = noOp;

@Input() id: string;
@Input() columns: any[] = [];
@Input() data: any[] = [];
@Input() requiredData: any[] = []; // list of data that cannot be un-selected
@Input() tableActions: any[] = [];
@Input() selectActions: any[] = [{ label: 'Delete', icon: 'delete', click: (items) => this.deleteItems(items) }];
@Input() minWidthFactor: number = 60;

@Input() showSelectColumns: boolean = true;

@Input() itemActions: any[] = [];
@Input() itemMenu: any[] = [];

@Input() sortBy: string;
@Input() tableTitle: string = undefined;

_dataTableService = new TdDataTableService();

filteredData: any[];
filteredTotal: number;
searchTerm: string = '';
refreshTimeout: any;

selectedRows: any[] = [];

sortOrder: TdDataTableSortingOrder = TdDataTableSortingOrder.Descending;

@Input() sortable: boolean = true;
@Input() clickable: boolean = true;
@Input() selectable: boolean = true;
@Input() multiple: boolean = true;
@Input() editable: boolean = true;

@Input() tableHeight: number = 500;

@Output() editRow: EventEmitter<any> = new EventEmitter();
@Output() deleteRow: EventEmitter<any> = new EventEmitter();

@ViewChild('dataTable') dataTable;
@ViewChild('searchBox') searchBox;

@Input() set value(v: any) {
    this.selectedRows = v;
    this._onChangeCallback(v);
}

constructor(
    private _dialog: VrpDialogService,
) { }

get value(): any { return this.selectedRows; }

writeValue(value: any) { // required by ControlValueAccessor interface
    if (value !== this.selectedRows) {
        this.selectedRows = value;
    }
}

registerOnChange(fn: any) { // required by ControlValueAccessor interface
    this._onChangeCallback = fn;
}

registerOnTouched(fn: any) { // required by ControlValueAccessor interface
    this._onTouchedCallback = fn;
}

ngOnChanges(changes: SimpleChanges) {
    if (this.itemMenu) {
        this.itemMenu = this.itemMenu.filter((im) => im.haspermission === true).length === 0 ? [] : this.itemMenu;
    }
    if (changes.columns && this.columns) {
        this._loadValuesToSessionStorage();
    }

    this.filter();
}

cancelSelection() {
    this.selectedRows = [];
    this._onChangeCallback(this.selectedRows);
    this._selectRequiredData();
}

filterColumns() {
    let formElements = this.columns.map((c, index) => ({ name: `c_${index}`, label: c.label, type: 'checkbox', default: !c.hidden }));
    // hide Column ID in Table SMS Template
    if (this.id === 'tablePlannerData_SMSTemplate') {
        const columns = formElements;
        formElements = [];
        columns.forEach((column) => {
            if (column.label !== 'Id') {
                formElements.push(column);
            }
        });
    }
    this._dialog.openDynamicEdit(formElements, undefined, 'Select columns')
        .subscribe((answer) => {
            if (answer) {
                this.columns.forEach((c, index) => {
                    c.hidden = !answer['c_' + index] && c.label !== '';
                });
                this._saveValuesToSessionStorage();
                this.filter(this._customFilteredData);
                this.refresh();
            }
        });
}

deleteItems(items) {
    _remove(this.data, (d) => items.indexOf(d) !== -1);
    this.deleteRow.emit(items);
    this.cancelSelection();
    this.filter(this._customFilteredData);
}

onSort(sortEvent: ITdDataTableSortChangeEvent): void {
    this.sortBy = sortEvent.name;
    this.sortOrder = sortEvent.order;
    this.filter(this._customFilteredData);
}

onSelectAny(): void {
    this._selectRequiredData();
}

@HostListener('window:resize', ['$event'])
onResize(event) {
    if (this.refreshTimeout) {
        clearTimeout(this.refreshTimeout);
    }

    this.refreshTimeout = setTimeout(() => {
        this.refresh();
    }, 1000);
}

search(searchTerm: string): void {
    this.searchTerm = searchTerm.trim();
    this.filter(this._customFilteredData);
}

clearSearchField() {
    this.searchBox.value = '';
}

filter(customFilteredData: any[] = undefined): void {
    this._customFilteredData = customFilteredData;

    if (!this.columns || !this.data) {
        return;
    }

    const excludedColumns: string[] = this.columns
        .filter((column: ITdDataTableColumn) => {
            return (((column.filter === undefined && column.hidden === true) ||
                (column.filter !== undefined && column.filter === false)));
        }).map((column: ITdDataTableColumn) => column.name);

    let newData: any[] = this.data;
    if (newData.length > 0) {
        if (!this._customFilteredData) {
            newData = this._dataTableService.filterData(newData, this.searchTerm, true, excludedColumns);
        } else {
            newData = this._dataTableService.filterData(this._customFilteredData, this.searchTerm, true, excludedColumns);
        }
        if (this.sortBy) {
            newData = _sortBy(newData, this.sortBy);
            if (this.sortOrder === TdDataTableSortingOrder.Descending) {
                newData.reverse();
            }
        }

        this.filteredTotal = newData.length;
    } else {
        this.filteredTotal = 0;
    }

    this.filteredData = newData;

    // select/unselect only the filtered data
    // this.selectedRows = this.selectedRows.filter((r) => this.filteredData.includes(r));

    this._selectRequiredData();

    this._onChangeCallback(this.selectedRows);
}

refresh() {
    this.dataTable.refresh();
}

private _selectRequiredData() {
    if (!this.requiredData || this.requiredData.length === 0) {
        return;
    }

    // add missing list of required data (i.e. cannot be unselected) back to selection list
    const missingRequiredData = _differenceWith(this.requiredData, this.selectedRows, _isEqual);
    this.selectedRows.push(...missingRequiredData);
}

private _loadValuesToSessionStorage() {
    if (this.id) {
        try {
            const defaultValues: boolean[] = JSON.parse(sessionStorage.getItem(this.id));
            if (defaultValues) {
                this.columns.forEach((c, i) => { if (c.name !== '_itemActions') { c.hidden = defaultValues[i]; } });
            }
        } catch (err) {
            console.trace(`Can load Table ${this.id} from sessionStorage`);
        }
    }
}

private _saveValuesToSessionStorage() {
    if (this.id) {
        try {
            const defaultValues: boolean[] = this.columns.map((c) => c.hidden);
            sessionStorage.setItem(this.id, JSON.stringify(defaultValues));
        } catch (err) {
            console.trace(`Can save Table ${this.id} to sessionStorage`);
        }
    }
}

}

调用vrp-table的代码如下:

    <vrp-table 
#vrpTable id='storePortal' [columns]="columns" [data]="allDeliveryDetailsRecords" [tableHeight]="tableHeight"
 [itemMenu]='tableItemMenus' [itemActions]='tableItemActions' [tableActions]='tableActions' selectable=false></vrp-table>

效果如下:

enter image description here

但是,我想为奇数行/偶数行设置不同颜色的行。我该怎么办?

谁能给我一些建议?

【问题讨论】:

  • 如何制作背景为白色的奇数行,但背景为蓝色的偶数行?非常感谢。

标签: angular


【解决方案1】:

对于不同的颜色行,可以使用 CSS 偶数和奇数规则。 这是一个link,可以帮助您入门。

tr:nth-child(even) {background: #CCC}
tr:nth-child(odd) {background: #FFF}

或者您可以为您的

使用引导类,例如 table-striped table-bordered
 <table id="myTable" class="table table-striped table-bordered" width="100%">

【讨论】:

  • 两者都无法工作,还有其他建议吗?非常感谢!
【解决方案2】:

@Syrbhi,

我尝试为

添加css

tr:nth-child(even) {背景:#CCC}

tr:nth-child(odd) {背景:#FFF}

不能为我工作。

也用于添加

这样,也不行,有什么建议吗?欣赏!

<td-data-table class="table table-striped table-bordered" #dataTable [data]="filteredData" [columns]="columns" [selectable]="selectable"
    [clickable]="clickable" [multiple]="multiple" [sortable]="sortable" [sortBy]="sortBy" [(ngModel)]="selectedRows"
    [sortOrder]="sortOrder" (sortChange)="onSort($event)" (rowClick)='editRow.emit($event.row)'
    (selectAll)="onSelectAny()" (rowSelect)="onSelectAny()" [style.height.px]="dataTable.hasData?tableHeight:50"
    [style.min-width]="dataTable.hasData?(columns.length * minWidthFactor + 'px'):'auto'">

【讨论】:

    猜你喜欢
    • 2014-07-20
    • 2012-08-19
    • 2021-12-31
    • 2013-08-21
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 2014-03-21
    • 2017-03-18
    相关资源
    最近更新 更多