风一更--软件开发--UI--Angular grid -- material table
target : angular material CSS-Grid table style
1.reference
2.practicial
2.practical


table attributes
1.整体:
2.details
1. frozen 表头

3. 条件性的高亮某个单元格. 也可以借此在 table 的各个行定义中动态添加 class, 来设置行背景色,CSS 配合添加样式。
理想情况下,直接 class= css 样式类。 后面直接赋值 (使用特殊类绑定设置个别 CSS 类)《Angular 高级编程 4th》p218
在宿主元素现有的CSS 类成员身份基础之上进行控制,而不是完全替换它们。

N/A 单元格高亮显式:




2023-06-19
mat-table angular *ngFor let index, odd event first, last 内置
1.表格自动编号, 主要的作用在, 表格排序发生变化时,序号自动更新。



=====
编号注意 表格导航 标号的处理:
https://stackoverflow.com/questions/49648270/how-to-define-index-in-angular-material-table/49648620
https://www.cnblogs.com/keatkeat/p/11004658.html
2023-06-20
material mat-table, css style 记录,最终采用的结果如下
table 在外部容器 windth 100%, 高度限定, 右侧有滑动条.
HTML 并不标准,与 material table mat-table 示例相比较



===============================================================================================
简单记录 无效的组合

----------

-------------------------

暂时先采用有效的 混合 HTML 标签.
2023-06-29
如果不需要高度限定,自由高度,可采用如下组合,
1. dispaly: grid , grid : auto
2. table


背景:表格 max-height 与 css grid template 一起使用时无法生效.
探索记录:
1. 使用 angular material Mat table 可生效.


同一个网格里的两个 块级元素 上下排布,居中对齐

差强人意的当前设计:
h2,h3 { margin: 1px 0 1px; border-bottom: 1px solid #8e3339; } .wrapper { width: 95%; max-width: 100em; margin: 0 auto; } .btn_config_op{ margin: 0 0 0 1.5em; } .subcategory { margin-top: 1.5em; border-bottom: 1px solid #8E3339; } .grid-config { display: -webkit-grid; display: grid; -webkit-grid-template-rows : auto auto auto; grid-template-rows: auto auto auto; -webkit-grid-template-columns: 45% 1fr; grid-template-columns: 45% 1fr; grid-column-gap: .5em; grid-row-gap: .5em; margin: 0 -.375em; } .grid-config-base { -webkit-grid-row: 1/-1; grid-row: 1/-1; -webkit-grid-column: 1; grid-column: 1; padding: .175em; margin: 0 .375em .375em; background-color: #8E3339; } .grid-config-condition { -webkit-grid-row: 1; grid-row: 1; -webkit-grid-column: 2; grid-column: 2; padding: .175em; margin: 0 .375em .375em; background-color: skyblue; } .grid-config-comparison{ -webkit-grid-row: 2; grid-row: 2; -webkit-grid-column:2; grid-column: 2; padding: .175em; margin: 0 .375em .375em; background-color: #FFC66D; } /********************************/ .mat-mdc-table{ font-family: "Lucida Sans", Verdana, Arial, sans-serif; border-collapse: collapse; overflow: auto; max-height: 900px; width: 100%; } .mat-mdc-table .mat-mdc-row:nth-child(even){ background-color: lightgray; } .mat-mdc-cell { word-break: break-word !important; font-size: xx-small; } .mat-column-index{ border-right: 1px solid currentColor; } /*.mat-column-index{ width: 35px; border-right: 1px solid currentColor; text-align: left; } .mat-column-partition{ width:110px; text-align:left; } .mat-column-segment{ width:150px; text-align:left; } .mat-column-valueType{ width:120px; } .mat-mdc-table .mat-column-charName{ max-width:100% }*/ .mat-mdc-option{ font-size: medium; } .grid-config article header { text-align: center; background-color: wheat; } .grid-config article header h3{ font-style: italic; }
<!-- Toolbar--> <header> <nav> <mat-toolbar color="primary"> <button mat-icon-button class="app-icon" aria-label="app icon-button with menu icon"> <mat-icon>menu</mat-icon> </button> <span>Data process & analysis platform</span> <span class="app-spacer"></span> <button mat-icon-button class="app-icon home-icon" aria-label="app icon-button with home icon" routerLink=""> <mat-icon aria-hidden="false" aria-label="app home icon" fontIcon="home">Home</mat-icon> </button> <button mat-icon-button class="app-icon" aria-label="app icon-button with share icon"> <mat-icon>share</mat-icon> </button> </mat-toolbar> </nav> </header> <ng-template cdk-portal #overlayConfig="cdkPortal"> <mat-spinner color="accent"></mat-spinner> </ng-template> <!-- main --> <main class="wrapper"> <mat-toolbar> <mat-slide-toggle [(ngModel)]="configDefault"> configuration default: {{configDefault}} </mat-slide-toggle> <span class="app-spacer"></span> <button class="btn_config_op" mat-stroked-button color="warn"> Reset </button> <button class="btn_config_op" mat-stroked-button color="primary" (click)="submitConfig()" [disabled]="overlayRefConfig"> Submit </button> </mat-toolbar> <section class="subcategory"> <mat-sidenav-container [hasBackdrop]="true"> <mat-sidenav disableClose [(opened)]="configDefault" ></mat-sidenav> <mat-sidenav-content> <div class="grid-config"> <article class="grid-config-base"> <header><h3>base</h3></header> <mat-table #tb_bases [dataSource]="configInit.bases" class="mat-elevation-z8" cdkDropList id="tb_id_bases" [cdkDropListData]="configInit.bases" [cdkDropListConnectedTo]="['tb_id_conditions','tb_id_comparisons']" (cdkDropListDropped)="dragDropEventHandler($event)"> <ng-container matColumnDef="index"> <mat-header-cell *matHeaderCellDef>no.</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{index + 1}}</mat-cell> </ng-container> <ng-container matColumnDef="partition"> <mat-header-cell *matHeaderCellDef>partition</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.partition}}</mat-cell> </ng-container> <ng-container matColumnDef="segment"> <mat-header-cell *matHeaderCellDef>segment</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.segment}}</mat-cell> </ng-container> <ng-container matColumnDef="charName"> <mat-header-cell *matHeaderCellDef>char name</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.charName}}</mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="metaColumns; sticky: true"></mat-header-row> <mat-row *matRowDef="let row; columns: metaColumns; let index = index" cdkDrag [cdkDragData]="row.data"></mat-row> </mat-table> </article> <article class="grid-config-condition"> <header><h3>condition</h3></header> <mat-table #tb_conditions [dataSource]="configInit.conditions" class="mat-elevation-z8" cdkDropList id="tb_id_conditions" [cdkDropListData]="configInit.conditions" [cdkDropListConnectedTo]="['tb_id_bases']" (cdkDropListDropped)="dragDropEventHandler($event)"> <ng-container matColumnDef="index"> <mat-header-cell *matHeaderCellDef>no.</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{index + 1}}</mat-cell> </ng-container> <ng-container matColumnDef="partition"> <mat-header-cell *matHeaderCellDef>partition</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.partition}}</mat-cell> </ng-container> <ng-container matColumnDef="segment"> <mat-header-cell *matHeaderCellDef>segment</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.segment}}</mat-cell> </ng-container> <ng-container matColumnDef="charName"> <mat-header-cell *matHeaderCellDef>charName</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.charName}}</mat-cell> </ng-container> <ng-container matColumnDef="valueType"> <mat-header-cell *matHeaderCellDef>value type</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{cell.valueType}}</mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="configColumns; sticky: true"></mat-header-row> <mat-row *matRowDef="let row; columns: configColumns;let index = index;" cdkDrag [cdkDragData]="row.data"></mat-row> </mat-table> </article> <article class="grid-config-comparison"> <header><h3>comparison</h3></header> <mat-table #tb_comparisons [dataSource]="configInit.comparisons" class="mat-elevation-z8" cdkDropList id="tb_id_comparisons" [cdkDropListData]="configInit.comparisons" [cdkDropListConnectedTo]="['tb_id_bases']" (cdkDropListDropped)="dragDropEventHandler($event)"> <ng-container matColumnDef="index"> <mat-header-cell *matHeaderCellDef>no.</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{index + 1}}</mat-cell> </ng-container> <ng-container matColumnDef="partition"> <mat-header-cell *matHeaderCellDef>partition</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.partition}}</mat-cell> </ng-container> <ng-container matColumnDef="segment"> <mat-header-cell *matHeaderCellDef>segment</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.segment}}</mat-cell> </ng-container> <ng-container matColumnDef="charName"> <mat-header-cell *matHeaderCellDef>char name</mat-header-cell> <mat-cell *matCellDef="let cell;let index = index">{{cell.charEntryMeta.charName}}</mat-cell> </ng-container> <ng-container matColumnDef="valueType"> <mat-header-cell *matHeaderCellDef>value type</mat-header-cell> <mat-cell *matCellDef="let cell"> <mat-select [(ngModel)]="cell.valueType" name="valueType"> <mat-option class="opt_valueType" *ngFor="let val of valueOptions" [value]="val.value"> {{val.viewValue}} </mat-option> </mat-select> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="configColumns; sticky: true"></mat-header-row> <mat-row *matRowDef="let row; columns: configColumns; let index = index;" cdkDrag [cdkDragData]="row.data"></mat-row> </mat-table> </article> </div> </mat-sidenav-content> </mat-sidenav-container> </section> </main>
import {Component, OnInit, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core';
import {
ConfigAquaEdgeRegPerform,
ConfigEntryAquaEdgeRegPerform
} from "../../model/config_aqua_edge_reg_perform/config_aqua_edge_reg_perform.model";
import {MatTable} from "@angular/material/table";
import {ActivatedRoute, Router} from "@angular/router";
import {ConfigAquaEdgeRegPerformRepository} from "../../model/config_aqua_edge_reg_perform/config_aqua_edge_reg_perform.repository";
import {ConfigAquaEdgeRegPerformRest} from "../../model/config_aqua_edge_reg_perform/config_aqua_edge_reg_perform.rest";
import {CdkOverlayOrigin, Overlay, OverlayConfig, OverlayRef} from "@angular/cdk/overlay";
import {CdkDragDrop, moveItemInArray, transferArrayItem} from "@angular/cdk/drag-drop";
import {TemplatePortal} from "@angular/cdk/portal";
interface valueEnum {
value: string;
viewValue: string;
}
@Component({
selector: 'app-config-aqua-edge-reg-perform',
templateUrl: './config-aqua-edge-reg-perform.component.html',
styleUrls: ['./config-aqua-edge-reg-perform.component.css']
})
export class ConfigAquaEdgeRegPerformComponent implements OnInit{
configDefault:boolean = true;
// @ts-ignore
configInit: ConfigAquaEdgeRegPerform;
// overlay
// @ts-ignore
overlayRefConfig: OverlayRef = null;
// @ts-ignore
@ViewChild("overlayConfig", {static: false}) templatePortal: TemplatePortal;
// table dropList config
metaColumns: string[] = ['index','partition', 'segment', 'charName'];
configColumns: string[] = ['index','partition', 'segment', 'charName', 'valueType'];
// @ts-ignore
@ViewChild('tb_bases') tb_bases: MatTable<ConfigEntryAquaEdgeRegPerform>;
// @ts-ignore
@ViewChild('tb_conditions') tb_conditions: MatTable<ConfigEntryAquaEdgeRegPerform>;
// @ts-ignore
@ViewChild('tb_comparisons') tb_comparisons: MatTable<ConfigEntryAquaEdgeRegPerform>;
valueOptions: valueEnum[] = [
{value: "STRING", viewValue: "String"},
{value: "NUMBER", viewValue: "Number"}
];
constructor(activatedRoute: ActivatedRoute,
private configRepository: ConfigAquaEdgeRegPerformRepository,
private configRest: ConfigAquaEdgeRegPerformRest,
private router: Router,
private overlay: Overlay) {
activatedRoute.params.subscribe(res => {
configRepository.handleInit(res);
this.configInit = configRepository.configInit;
})
}
ngOnInit(): void {
}
dragDropEventHandler(event: CdkDragDrop<any[]>) {
if (event.previousContainer === event.container) {
moveItemInArray(
event.container.data,
event.previousIndex,
event.currentIndex);
} else {
transferArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex);
}
this.tb_bases.renderRows();
this.tb_conditions.renderRows();
this.tb_comparisons.renderRows();
}
backHome() {
this.router.navigateByUrl("/home");
}
submitConfig() {
this.openOverlay();
this.applyConfig();
}
applyConfig() {
let config: ConfigAquaEdgeRegPerform;
if (this.configDefault) {
config = this.buildDefaultConfig();
} else {
config = this.buildCustomizeConfig();
}
// @ts-ignore
this.configRest.postConfig(config).subscribe(res => {
this.handleConfigAppliedRes(res);
});
}
buildDefaultConfig() {
return new ConfigAquaEdgeRegPerform("default", [], [], []);
}
buildCustomizeConfig() {
return new ConfigAquaEdgeRegPerform("customize",
this.configInit.conditions,
[],
this.configInit.comparisons);
}
handleConfigAppliedRes(response: any) {
if (response.statusCode === "NORMAL") {
this.transferToReport(response);
return;
} else {
alert(response.statusCode);
}
}
private transferToReport(response: any) {
const data = {
data: JSON.stringify(response.data)
};
this.router.navigate(["/aqua-edge-regression-performance-report", data]);
}
// overlay
openOverlay() {
const config = new OverlayConfig();
config.positionStrategy = this.overlay.position()
.global().centerVertically().centerHorizontally();
config.disposeOnNavigation = true;
config.hasBackdrop = true;
this.overlayRefConfig = this.overlay.create(config);
this.overlayRefConfig.attach(this.templatePortal);
}
}




===============================================================================================

浙公网安备 33010602011771号