• angular-cdk 探索


    安装(文档参考版本12.1.1)

    ng add @angular/cdk
    添加css
    @import '~@angular/cdk/overlay-prebuilt.css';
    

    执行两个方法

    <button (click)="add();add1()">Click</button>
    

    获取焦点失去焦点

    css

    .box .cdk-focused{
      background-color: red;
    }
    

    html

    <div class="box">
      <button  cdkMonitorSubtreeFocus (cdkFocusChange)="add($event)">Click</button>
    </div>
    

    ts

     add(e: any) { // 点击的  mouse|touch
        console.log(e);
      }
    

    点击的时候焦点

    添加的时候class不一样

    html点击的时候添加的参数不一样, 或者class不一样

    'touch' | 'mouse' | 'keyboard' | 'program' | null;

    <button (click)="focusMonitor.focusVia(aaa,'mouse')">click1</button>
    <div class="box">
      <button #aaa>我是box</button>
    </div>
    

    ts

    export class ThreeComponent implements OnInit, AfterViewInit, OnDestroy {
      @ViewChild('aaa') aaa!: ElementRef<HTMLElement>;
    
      constructor(
        public focusMonitor: FocusMonitor,
      ) {
      }
      ngAfterViewInit() {
        this.focusMonitor.monitor(this.aaa).subscribe(origin => {
          console.log(origin);
        })
      }
      ngOnDestroy() {
        this.focusMonitor.stopMonitoring(this.aaa)
      }
    }
    

    复制剪贴板

    1

    <button [cdkCopyToClipboard]="text1">复制到剪贴板</button>
    
      text1='我是复制的内容'
    

    2

    <button (click)="copyHome()">复制到剪贴板</button>
    
      constructor(
        private clip: Clipboard
      ) {}
    
      copyHome() {
        this.clip.copy('我是复制的文本')
      }
    

    输入框的实用api

    coerceBooleanProperty

    输入的值undefined/null/'false'/false 都为 false

    export function coerceBooleanProperty(value: any): boolean {
      return value != null && `${value}` !== 'false';
    }
    
    undefined/null/'false'/false 都为 false
    
    官网的案例
    [disabled]=""  会传递的值就行分析
      @Input()
      get disabled() { return this._disabled; }
      set disabled(value: any) {
        this._disabled = coerceBooleanProperty(value);
      }
      private _disabled = false;
    
    

    CoerceNumberProperty

    输入数字的限制

    源码
    export function coerceNumberProperty(value: any): number;
    export function coerceNumberProperty<D>(value: any, fallback: D): number | D;
    export function coerceNumberProperty(value: any, fallbackValue = 0) {
      return _isNumberValue(value) ? Number(value) : fallbackValue;
    }
    export function _isNumberValue(value: any): boolean {
      return !isNaN(parseFloat(value as any)) && !isNaN(Number(value));
    }
    // 当输入不是数字,尝试parseFloat转换,然后判断isNaN检验, 
    // 如果不是使用默认值
    CoerceNumberProperty('1.s',2)
    

    NumberInput

    export type BooleanInput = string | boolean | null | undefined;
    

    BooleanInput

    export type BooleanInput = string | boolean | null | undefined;
    

    coerceElement

    将ElementRef或Element强制转换为element。

    export function coerceElement<T>(elementOrRef: ElementRef<T> | T): T {
      return elementOrRef instanceof ElementRef ? elementOrRef.nativeElement : elementOrRef;
    }
    

    使用

      @ViewChild('aaa') aaa!: ElementRef<HTMLElement>;
    // 结果一样
        ngAfterViewInit() {
        console.log(this.aaa.nativeElement);
        console.log(coerceElement(this.aaa));
      }
    

    SelectionModel

    多选或者取消

    <!--  hasValue 是否有值-->
    <label nz-checkbox [nzChecked]="selection.hasValue() &&isAll()"
           [nzIndeterminate]="selection.hasValue()&&!isAll()" (nzCheckedChange)="allToggle()">全选</label>
    <div *ngFor="let item of dataArr">
      <label nz-checkbox [(ngModel)]="item.checked" (ngModelChange)="selection.toggle(item.id)">{{item.id}}</label>
    </div>
    <button (click)="getArr()">查询状态</button>
    
    export class ThreeComponent implements OnInit, OnDestroy {
    // 多选框
      selection = new SelectionModel<Element>(true, [])
      // 数据
      // 全选或者不全选
      numBool = false;
      indeterminate = false;
      dataArr: Array<any> = [
        {id: 1, checked: false},
        {id: 2, checked: false},
        {id: 3, checked: false},
        {id: 4, checked: false},
      ]
    
      // 全选
      isAll() {
        const numSelected = this.selection.selected.length;
        const DateNum = this.dataArr.length;
        return numSelected === DateNum;
      }
    
      // 切换点击全选的
      allToggle(): void {
        if (this.isAll()) {
          this.selection.clear()
          this.dataArr.forEach(row => {
            row.checked = false;
          })
        } else {
          this.dataArr.forEach(row => {
            row.checked = true;
            this.selection.select(row.id)
          })
        }
      }
      getArr() {
        // 拿到查询数组
        console.log(this.selection.selected);
      }
    }
    

    cdkDrag 拖拽

    demo1, 单个数组拖拽

    <ul cdkDropList (cdkDropListDropped)="dropClick($event)">
      <li *ngFor="let item of textArr" cdkDrag>{{item.text}}</li>
    </ul>
    
    ========================
    textArr = [
        {text: '11111111111111'},
        {text: '22222222222222'},
        {text: '33333333333333'},
        {text: '44444444444444'},
        {text: '55555555555555'},
      ]
    
      dropClick($event: any) {
        moveItemInArray(this.textArr, $event.previousIndex, 		                           $event.currentIndex)
      }
    

    自定义拖动预览(cdkDragPreview)

    <div cdkDropList  (cdkDropListDropped)="drop($event)">
      <div  *ngFor="let movie of movies" cdkDrag>
        {{movie.title}}
        <img *cdkDragPreview [src]="movie.poster" [alt]="movie.title">
      </div>
    </div>
    
    movies = [
        {
          title: 'Episode V - The Empire Strikes Back',
          poster: 'https://upload.wikimedia.org/wikipedia/en/3/3c/SW_-_Empire_Strikes_Back.jpg'
        },
        {
          title: 'Episode VI - Return of the Jedi',
          poster: 'https://upload.wikimedia.org/wikipedia/en/b/b2/ReturnOfTheJediPoster1983.jpg'
        },
        {
          title: 'Episode VII - The Force Awakens',
          poster: 'https://upload.wikimedia.org/wikipedia/en/a/a2/Star_Wars_The_Force_Awakens_Theatrical_Poster.jpg'
        },
        {
          title: 'Episode VIII - The Last Jedi',
          poster: 'https://upload.wikimedia.org/wikipedia/en/7/7f/Star_Wars_The_Last_Jedi.jpg'
        },
        {
          title: 'Episode IX – The Rise of Skywalker',
          poster: 'https://upload.wikimedia.org/wikipedia/en/a/af/Star_Wars_The_Rise_of_Skywalker_poster.jpg'
        }
      ];
      drop(event: CdkDragDrop<{title: string, poster: string}[]>) {
        moveItemInArray(this.movies, event.previousIndex, event.currentIndex);
      }
    

    自定义拖动占位符(*cdkDragPlaceholder)

    <div cdkDropList (cdkDropListDropped)="drop($event)">
      <div *ngFor="let movie of movies" cdkDrag>
        <div *cdkDragPlaceholder style="20px;height: 20px;"></div>
        {{movie.title}}
        <!--    <img *cdkDragPreview [src]="movie.poster" [alt]="movie.title">-->
      </div>
    </div>
    

    设置方向

    						水平				垂直
    type DropListOrientation = 'horizontal' | 'vertical';
    
    <div cdkDropList (cdkDropListDropped)="drop($event)" cdkDropListOrientation="horizontal" style="display: flex">
      <div *ngFor="let movie of movies" cdkDrag  style=" 200px;">
        <div *cdkDragPlaceholder style="200px;"></div>
        {{movie.title}}
     </div>
    </div>
    

    限制范围(cdkDragBoundary)

    限制反向(cdkDragLockAxis)

    <div class="aaa">
      <div class="bbb" cdkDrag cdkDragBoundary=".aaa"  cdkDragLockAxis = "x"></div>
    </div>
    

    demo2, 两个数组拖拽

    <ul cdkDropList
        #aa="cdkDropList"
        [cdkDropListData]="textArr"
        [cdkDropListConnectedTo]="[bb]"
        (cdkDropListDropped)="dropClick($event)">
      <li *ngFor="let item of textArr" cdkDrag>{{item.text}}</li>
    </ul>
    <hr>
    <ul cdkDropList
        #bb="cdkDropList"
        [cdkDropListData]="textArrTwo"
        [cdkDropListConnectedTo]="[aa]"
        (cdkDropListDropped)="dropClick($event)">
      <li *ngFor="let item of textArrTwo" cdkDrag>{{item.text}}</li>
    </ul>
    
      textArr = [
        {text: '11111111111111'},
        {text: '22222222222222'},
        {text: '33333333333333'},
        {text: '44444444444444'},
        {text: '55555555555555'},
      ]
      textArrTwo = [
        {text: 'aaaaaaaaaaaaaa'},
        {text: 'bbbbbbbbbbbbbb'},
        {text: 'cccccccccccccc'},
        {text: 'eeeeeeeeeeeeee'},
        {text: 'ffffffffffffff'},
      ]
      dropClick(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);
        }
      }
    

    上面那种形式, 可以进行简化

    <div cdkDropListGroup>
      <ul cdkDropList
          [cdkDropListData]="textArr"
          (cdkDropListDropped)="dropClick($event)">
        <li *ngFor="let item of textArr" cdkDrag>{{item.text}}</li>
      </ul>
      <hr>
      <ul cdkDropList
          [cdkDropListData]="textArrTwo"
          (cdkDropListDropped)="dropClick($event)">
        <li *ngFor="let item of textArrTwo" cdkDrag>{{item.text}}</li>
      </ul>
    </div>
    

    手柄自定义拖动区域

    <div class="aaa" cdkDrag>
      <div class="bbb" cdkDragHandle>点我</div>
    </div>
    
    .aaa{
       200px;
      height: 200px;
      background-color: #783ce8;
      .bbb{
         40px;
        height: 40px;
        background-color: #af0b0b;
      }
    }
    

    检测屏幕的变化

    export class ThreeComponent implements OnInit, OnDestroy {
      destroyed = new Subject<void>();
      constructor(private breakpoint:BreakpointObserver) {
        breakpoint.observe([
          // (max- 599.98px)
          Breakpoints.XSmall,
          // (min- 600px) and (max- 959.98px)
          Breakpoints.Small,
          // (min- 960px) and (max- 1279.98px)
          Breakpoints.Medium,
          // (min- 1280px) and (max- 1919.98px)
          Breakpoints.Large,
          // (min- 1920px)
          Breakpoints.XLarge,
        ]).pipe(takeUntil(this.destroyed)).subscribe(result=>{
          for (let [key,value] of Object.entries(result.breakpoints)){
            if(value){
              console.log(key);
            }
          }
    
        })
      }
      ngOnDestroy() {
        this.destroyed.next()
      }
    }
    

    检查当前视口的大小

    breakpointObserver.isMatched('(max- 599px)')
    

    检测ng-content 的内容发生变化

    添加模块

    import {ObserversModule} from '@angular/cdk/observers';
    

    上一个小案例

    <button (click)="clickNum()">Click++</button>
    <app-six>
      <h1>{{num}}</h1>
    </app-six>
    
      num=1;
      clickNum(){
        ++this.num
      }
    

    <div (cdkObserveContent)="clickChanged()">
      <ng-content></ng-content>
    </div>
    
      clickChanged() {
        console.log('执行了');
      }
    

    弹框

    demo1

    <button (click)=" isOpen=!isOpen" cdkOverlayOrigin #box="cdkOverlayOrigin">Click 1</button>
    
    <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]="box" [cdkConnectedOverlayOpen]="isOpen">
      <div>我是一个div</div>
    </ng-template>
    
      isOpen = false;
    
    

    使用添加弹框组件的形式

    <button (click)="open1()">点击我</button>
    
    export class ThreeComponent implements OnInit, OnDestroy {
      overlayRef!: OverlayRef;
      fileComponent!: ComponentPortal<SixComponent>;
    
      constructor(public overlay: Overlay,) {
    
      }
    
      isOpen = false;
    
      ngOnInit(): void {
        // 容器
        this.overlayRef = this.overlay.create()
        // 添加容器的组件
        this.fileComponent = new ComponentPortal(SixComponent);
        //添加最外层的class
        this.overlayRef.addPanelClass("aaaa");
      }
    
      open1() {
        this.isOpen = !this.isOpen;
        if (this.isOpen) {
          this.overlayRef.attach(this.fileComponent);
        } else {
          this.overlayRef.detach()
        }
      }
    
      ngOnDestroy() {
        this.overlayRef.dispose()
      }
    }
    

    可以用发布订阅的形式传递数据

    决定自己的高度的是你的态度,而不是你的才能

    记得我们是终身初学者和学习者

    总有一天我也能成为大佬

  • 相关阅读:
    浏览器渲染原理
    element 表单清空提示语(单个 )
    同步异步
    数组的浅克隆
    ... 运算符
    解构赋值
    vue 中el-input 为number 如何控制不允许输入负号
    Android SDK Manager 更新代理配置
    Android 设计中的.9.png
    Android 编程下的 Secret Code
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/15027155.html
Copyright © 2020-2023  润新知