雪一更--软件开发--UI Angular material
目的:基于组件完整性和适用场景,采用 Angular material UI
1.resource:
1.sass 转 css : https://www.sassmeister.com/
2.highCharts : https://www.highcharts.com/
3. Angular Flex-Layout 官网: https://github.com/angular/flex-layout
ng add @angular/material npm i highcharts-angular --save npm i highcharts --save npm i @angular/flex-layout @angular/cdk --save
1. material 官网
angular 引入 material
1. npm install --save @angular/material @angular/cdk @angular/animations
2. 核心模块 import BrowserAnimationsModule 和相应的组件, 如要禁止 material 动画, import NoopAnimationsModule
3.项目的根目录下 style.css import
4. mat-slide-toogle, mat-slider, matTooltip 等需要 import hammerjs . npm install --save hammerjs
5. 如果需要 material icon, 需要在根目录 index.html 引入

2. dragDrop 组件使用时,三个table 交互。需要指定两两可交互



2023-02-14
1. install
ng new dashboard ng add @angular/material npm i highcharts-angular --save npm i highcharts --save npm i @angular/flex-layout @angular/cdk --save


2023-02-17



2023-03-04
Drag-and-Drop 三个列表的控制
单项的精细控制可使用 item 级别 加上 prediacation 表达式操作。
disable 控制.




dialog, drag-and-drop, overlay,

<button (click)="openDialog()">Open a draggable dialog</button> <ng-template> <div class="example-dialog-content" cdkDrag cdkDragRootElement=".cdk-overlay-pane"> Drag the dialog around! </div> </ng-template>
import {AfterViewInit, Component, OnDestroy, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core';
import {Overlay, OverlayRef} from "@angular/cdk/overlay";
import {TemplatePortal} from "@angular/cdk/portal";
@Component({
selector: 'app-diagram',
templateUrl: './diagram.component.html',
styleUrls: ['./diagram.component.css']
})
export class DiagramComponent implements AfterViewInit, OnDestroy{
// @ts-ignore
@ViewChild(TemplateRef) _dialogTemplate: TemplateRef<any>;
// @ts-ignore
private _overlayRef: OverlayRef;
// @ts-ignore
private _portal: TemplatePortal;
constructor(private _overlay: Overlay, private _viewContainerRef:ViewContainerRef){}
ngAfterViewInit(){
this._portal = new TemplatePortal(this._dialogTemplate,this._viewContainerRef);
this._overlayRef = this._overlay.create({
positionStrategy:
this._overlay.position().global().centerHorizontally()
.centerVertically(),
hasBackdrop:true,
});
this._overlayRef.backdropClick().subscribe(
()=> this._overlayRef.detach());
}
ngOnDestroy(){
this._overlayRef.dispose();
}
openDialog(){
this._overlayRef.attach(this._portal);
}
}
.example-dialog-content{ width: 200px; height: 200px; border: solid 1px #ccc; color: rgba(0,0,0,0.87); cursor:move; display:flex; justify-content: center; align-items: center; background: #fff; border-radius: 4px; transition: box-shadow 200ms cubic-bezier(0,0,0.2,1); box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12); } .example-dialog-content:active{ box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); }
2023-03-05
disable item, css



禁止排序, 回来的项继续保持原来的顺序。(存疑)

排序到特定的位置(序号)上.


table drag - and - drop





<div class="example-container"> <table #baseTable mat-table [dataSource]="dataSourceCnd" class="mat-elevation-z8" cdkDropList id="tb_condition" [cdkDropListData]="dataSourceCnd" [cdkDropListConnectedTo]="['tb_base']" (cdkDropListDropped)="dropTbCondition($event)"> <ng-container matColumnDef="position"> <th mat-header-cell *matHeaderCellDef>No. </th> <td mat-cell *matCellDef="let element">{{element.position}}</td> </ng-container> <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDef>Name</th> <td mat-cell *matCellDef="let element">{{element.name}}</td> </ng-container> <ng-container matColumnDef="quantity"> <th mat-header-cell *matHeaderCellDef> quantity</th> <td mat-cell *matCellDef="let element"> <mat-form-field> <input matInput type="text" [value]="element.quantity"> </mat-form-field> </td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;" cdkDrag [cdkDragData]="row.data"></tr> </table> </div> <div class="example-container"> <table #cndTable mat-table [dataSource]="dataSourceBase" class="mat-elevation-z8" id="tb_base" cdkDropList [cdkDropListData]="dataSourceBase" [cdkDropListConnectedTo]="['tb_condition']" (cdkDropListDropped)="dropTbBase($event)"> <ng-container matColumnDef="position"> <th mat-header-cell *matHeaderCellDef>No. </th> <td mat-cell *matCellDef="let element">{{element.position}}</td> </ng-container> <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDef>Name</th> <td mat-cell *matCellDef="let element">{{element.name}}</td> </ng-container> <ng-container matColumnDef="quantity"> <th mat-header-cell *matHeaderCellDef> quantity</th> <td mat-cell *matCellDef="let element"> <mat-form-field> <input matInput type="text" [value]="element.quantity"> </mat-form-field> </td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;" cdkDrag [cdkDragData]="row.data"></tr> </table> </div>
import {Component, ViewChild} from '@angular/core';
import {CdkDragDrop, moveItemInArray, transferArrayItem} from "@angular/cdk/drag-drop";
import {MatTable} from "@angular/material/table";
export interface PeriodicElement {
name: string;
position: number;
quantity:number;
}
const conditions: PeriodicElement[] = [
{position: 1, name: 'Hydrogen',quantity:10},
{position: 2, name: 'Helium', quantity:20},
{position: 3, name: 'Lithium', quantity:30}
];
const base: PeriodicElement[] = [
{position: 8, name: 'Oxygen',quantity:10},
{position: 9, name: 'Fluorine',quantity:20},
{position: 10, name: 'Neon', quantity:30}
];
@Component({
selector: 'app-user-config',
templateUrl: './user-config.component.html',
styleUrls: ['./user-config.component.css']
})
export class UserConfigComponent {
displayedColumns: string[] = ['position', 'name', 'quantity'];
dataSourceCnd = conditions;
dataSourceBase = base;
// @ts-ignore
@ViewChild('baseTable') cndTable:MatTable<PeriodicElement>;
// @ts-ignore
@ViewChild('cndTable') baseTable:MatTable<PeriodicElement>;
dropTbCondition(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.cndTable.renderRows();
this.baseTable.renderRows();
}
dropTbBase(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.cndTable.renderRows();
this.baseTable.renderRows();
}
}
--------------------------------------
三个表 有条件的拖拽
<mat-card> <mat-card-header> <mat-card-title>Configuration</mat-card-title> </mat-card-header> <mat-card-content> <section class="config-toolbar-section"> <label class="config-toolbar-margin">configuration:</label> <mat-radio-group [(ngModel)]="userSpecify.config"> <mat-radio-button class="config-toolbar-margin" value="default">default</mat-radio-button> <mat-radio-button class="config-toolbar-margin" value="customize">customize</mat-radio-button> </mat-radio-group> </section> </mat-card-content> </mat-card> <form #customizeForm="ngForm" novalidate enctype="multipart/form-data" (ngSubmit)="submitCustomizeForm(customizeForm)"> <section> <table mat-table #tb_configConditions [dataSource]="conditions" class="mat-elevation-z8" cdkDropList id="tb_id_configConditions" [cdkDropListData]="conditions" [cdkDropListConnectedTo]="['tb_id_configBase']" (cdkDropListDropped)="dropTbConfig($event)"> <ng-container matColumnDef="priority"> <th mat-header-cell *matHeaderCellDef>priority</th> <td mat-cell *matCellDef="let cell">{{cell.priority}}</td> </ng-container> <ng-container matColumnDef="partition"> <th mat-header-cell *matHeaderCellDef>partition</th> <td mat-cell *matCellDef="let cell">{{cell.specifyMeta.partition}}</td> </ng-container> <ng-container matColumnDef="segment"> <th mat-header-cell *matHeaderCellDef>segment</th> <td mat-cell *matCellDef="let cell">{{cell.specifyMeta.segment}}</td> </ng-container> <ng-container matColumnDef="charName"> <th mat-header-cell *matHeaderCellDef>name</th> <td mat-cell *matCellDef="let cell">{{cell.specifyMeta.charName}}</td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayMetaColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayMetaColumns;" cdkDrag [cdkDragData]="row.data"></tr> </table> </section> <section> <table mat-table #tb_configBase [dataSource]="base" class="mat-elevation-z8" cdkDropList id="tb_id_configBase" [cdkDropListData]="base" [cdkDropListConnectedTo]="['tb_id_configConditions','tb_id_configComparisons']" (cdkDropListDropped)="dropTbConfig($event)"> <ng-container matColumnDef="priority"> <th mat-header-cell *matHeaderCellDef>priority</th> <td mat-cell *matCellDef="let cell">{{cell.priority}}</td> </ng-container> <ng-container matColumnDef="partition"> <th mat-header-cell *matHeaderCellDef>partition</th> <td mat-cell *matCellDef="let cell">{{cell.specifyMeta.partition}}</td> </ng-container> <ng-container matColumnDef="segment"> <th mat-header-cell *matHeaderCellDef>segment</th> <td mat-cell *matCellDef="let cell">{{cell.specifyMeta.segment}}</td> </ng-container> <ng-container matColumnDef="charName"> <th mat-header-cell *matHeaderCellDef>name</th> <td mat-cell *matCellDef="let cell">{{cell.specifyMeta.charName}}</td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayMetaColumns"></tr> <tr mat-row *matRowDef="let row; columns:displayMetaColumns;" cdkDrag [cdkDragData]="row.data"></tr> </table> </section> <section> <table mat-table #tb_comparisons [dataSource]="comparisons" class="mat-elevation-z8" cdkDropList id="tb_id_configComparisons" [cdkDropListData]="comparisons" [cdkDropListConnectedTo] = "['tb_id_configBase']" (cdkDropListDropped)="dropTbConfig($event)"> <ng-container matColumnDef="priority"> <th mat-header-cell *matHeaderCellDef>priority</th> <td mat-cell *matCellDef="let cell">{{cell.priority}}</td> </ng-container> <ng-container matColumnDef="partition"> <th mat-header-cell *matHeaderCellDef>partition</th> <td mat-cell *matCellDef="let cell">{{cell.specifyMeta.partition}}</td> </ng-container> <ng-container matColumnDef="segment"> <th mat-header-cell *matHeaderCellDef>segment</th> <td mat-cell *matCellDef="let cell">{{cell.specifyMeta.segment}}</td> </ng-container> <ng-container matColumnDef="charName"> <th mat-header-cell *matHeaderCellDef>name</th> <td mat-cell *matCellDef="let cell">{{cell.specifyMeta.charName}}</td> </ng-container> <ng-container matColumnDef="valueType"> <th mat-header-cell *matHeaderCellDef>type</th> <td mat-cell *matCellDef="let cell"> <mat-form-field appearance="fill"> <mat-select [(ngModel)]="cell.data" name="valueType"> <mat-option *ngFor="let val of valueOptions" [value]="val.value"> {{val.viewValue}} </mat-option> </mat-select> </mat-form-field> </td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayConfigColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayConfigColumns;" cdkDrag [cdkDragData]="row.data"></tr> </table> </section> <section> <div class="form-button-row"> <button mat-raised-button color="reset" type="reset">Reset</button> <button mat-raised-button color="primary" type="submit">Submit</button> </div> </section> </form>
import {Component, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {SpecificationRepository} from "../../model/specification/specification.repository";
import {SpecifiedMap, SpecifyEntry, UserSpecify} from "../../model/specification/specification.model";
import {NgForm} from "@angular/forms";
import {SpecificationRequest} from "../../model/specification/specification.request";
import {CdkDragDrop, moveItemInArray, transferArrayItem} from "@angular/cdk/drag-drop";
import {MatTable} from "@angular/material/table";
interface valueEnum{
value: string;
viewValue: string;
}
@Component({
selector: 'app-config',
templateUrl: './config.component.html',
styleUrls: ['./config.component.css']
})
export class ConfigComponent implements OnInit{
// @ts-ignore
preConfig:SpecifiedMap ;
// @ts-ignore
conditions:SpecifyEntry[] ;
// @ts-ignore
base:SpecifyEntry[];
// @ts-ignore
comparisons:SpecifyEntry[];
/*
configDefault:'default' | 'customize' = 'default';
*/
// @ts-ignore
userSpecify:UserSpecify = new UserSpecify("default",null);
displayMetaColumns: string[] = ['priority', 'partition', 'segment', 'charName'];
displayConfigColumns:string[] = ['priority','partition','segment','charName','valueType']
valueOptions: valueEnum[] = [
{value:"STRING",viewValue:"String"},
{value:"NUMBER",viewValue:"Number"},
];
// @ts-ignore
@ViewChild('tb_configConditions') tbConfigConditions:MatTable<SpecifyEntry>;
// @ts-ignore
@ViewChild('tb_configBase') tbConfigBase:MatTable<SpecifyEntry>;
// @ts-ignore
@ViewChild('tb_comparisons') tbConfigComparisons:MatTable<SpecifyEntry>;
constructor(activatedRoute:ActivatedRoute,
specificationRepository:SpecificationRepository,
private specificationRequest:SpecificationRequest,
private router:Router){
activatedRoute.params.subscribe(responseSpecification=>{
specificationRepository.receive(responseSpecification);
this.preConfig = specificationRepository.preConfig;
this.conditions = this.preConfig.conditions;
this.base = this.preConfig.base;
this.comparisons = this.preConfig.comparisons;
})
}
// config table drag-and-drop
dropTbConfig(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.tbConfigConditions.renderRows();
this.tbConfigBase.renderRows();
this.tbConfigComparisons.renderRows();
}
submitCustomizeForm(ngForm:NgForm){
// todo delete this,
if(this.userSpecify.config==="default"){
alert(this.userSpecify.config);
}
if(this.userSpecify.config==="customize"){
alert(this.userSpecify.config);
}
this.specificationRequest.postUserSpecify(this.userSpecify)
.subscribe(applySpecifyResponse => this.handleApplySpecifyResponse(applySpecifyResponse));
}
private handleApplySpecifyResponse(applySpecifyResponse:any){
// valid
// router
alert(applySpecifyResponse);
}
ngOnInit(): void {
}
}
2023-04-02
angular build error,

修改 angular.json 里面配置:

2023-05-06
table 中 select 的设置
1.component.ts


2.html

1.progress spinner, 进度指示

table 标签中使用 cdkDragDisabled 无效

2023-08-18
Angular module 组织依赖:
declarations 声明了组件的部分,
imports 要引入相应依赖



浙公网安备 33010602011771号