雪一更--软件开发--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>
HTML
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);
  }

}
typeScript
.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);
}
CSS

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>
html
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();
  }
}
typeScript

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

三个表 有条件的拖拽

<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>
html
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 {
  }
}
component.ts

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 要引入相应依赖


 

posted @ 2022-12-27 19:02  君子之行  阅读(12)  评论(0)    收藏  举报