zoukankan      html  css  js  c++  java
  • angular的学习进阶(十七)


    虚拟滚动条

    资料

    响应式应用

    https://responsively.app/download

    有趣的代码

    https://1loc.dev/
    

    rxjs 运算符相互的区别

    export type Shape = '1' | '2';
    export type Card = '3' | '4';
     public shapes$ = new Subject<Shape>();
     public cards$ = new Subject<Card>();
    

    zip 每次压缩的可观察值,一组一组发

        zip(of(1),of(2)).subscribe(console.log)
    
    ngOnInit(): void {
        zip(this.shapes$, this.cards$).subscribe(console.log);
        this.shapes$.next('1');
        this.cards$.next('3');
    
        this.shapes$.next('2');
        this.cards$.next('3');
    
        this.shapes$.next('1');
        this.cards$.next('4');
        // 不需要complete 也能执行
      }
      
      ["1", "3"] 
      ["2", "3"]
      ["1", "4"]
    

    forkJoin 仅在完成之后才发出最后一组的值

        forkJoin(of(1),of(2)).subscribe(console.log)
    	[1,2]
    
    ngOnInit(): void {
        forkJoin(this.shapes$, this.cards$).subscribe(console.log);
        this.shapes$.next('1');
        this.cards$.next('3');
    
        this.shapes$.next('2');
        this.cards$.next('3');
    
        this.shapes$.next('1');
        this.cards$.next('4');
        // 在complete完成后才会执行
        this.shapes$.complete()
        this.cards$.complete()
      }
      
      ["1", "4"]
    

    combineLatest 每次可观察对象发出新值,会发出之前的值

     ngOnInit(): void {
        combineLatest(this.shapes$, this.cards$).subscribe(console.log);
        this.shapes$.next('1');
        this.cards$.next('3');
    	// 2次
        this.shapes$.next('2');
        this.cards$.next('3');
    	// 2次
        this.shapes$.next('1');
        this.cards$.next('4');
    	//1 次
    	// 不需要complete
    }
    //  ["1", "3"]
    //  ["2", "3"]
    // ["2", "3"]
    // ["1", "3"]
    // ["1", "4"]
    

    distinctUntilChanged 运算符

    number,string

     [1, 2, 3, 1, 3]   of(1, 1, 2, 2, 3, 3, 1, 3, 3, 3).pipe(distinctUntilChanged(), toArray()).subscribe(console.log);
       // [1, 2, 3, 1, 3]
        of('a', 'A', 'b', 'c', 'D', 'd', 'e', 'f', 'G', 'g', 'h').pipe(
          // 把前一个字和后一个值转化成小写,所以相同的就可以跳过
          // c ,p 可以理解成前一个值,后一个值
          distinctUntilChanged((c, p) => c.toLowerCase() === p.toLowerCase()),
          toArray()
        ).subscribe(console.log);
      //  ["a", "b", "c", "D", "e", "f", "G", "h"]
    

    对象流

    将对对象引用的比较,而不是对象属性值得比较

     from([obj,obj,obj]).pipe(distinctUntilChanged()).subscribe(console.log)
      // {name: "xxx"}
    

    但是我们写成函数进行判断

       from([
          { name: 'Porsche', model: '911' },
          { name: 'Porsche', model: '911' },
          { name: 'Ferrari', model: 'F40' }
        ]).pipe(
          distinctUntilChanged((p,n)=>{
            return p.name===n.name&&p.model===n.model
          }),
        ).subscribe(console.log)
    // {name: "Porsche", model: "911"}
    //  {name: "Ferrari", model: "F40"}
    

    两个参数的情况

     from([
          { name: 'Porsche', model: '911' },
          { name: 'PORSCHE', model: '911' },
          { name: 'Ferrari', model: 'F40' },
          { name: 'FERRARI', model: 'F40' },
        ]).pipe(
          distinctUntilChanged(
            (p,n)=>{
            return p.toLowerCase()===n.toLowerCase()
          },/*第二个函数你可以理解成 c=>v.name
            :{}  我差点蒙蔽了,其实就是做了typescript做的类型限制
          */
            (car:{name:string,model:string})=>car.name
          ),
        ).subscribe(console.log)
       // {name: "Porsche", model: "911"}
       // {name: "Ferrari", model: "F40"}
    

    源码地址

    官方用法地址

    封装input 延迟输入指令

    ng g d delayed/delayed-input
    
    import {Directive, OnInit,OnDestroy,ElementRef, EventEmitter, Input, Output} from '@angular/core';
    import {from, fromEvent, Subject, timer} from 'rxjs';
    import {debounce, distinctUntilChanged, takeUntil} from 'rxjs/operators';
    
    @Directive({
      selector: '[appDelayedInput]'
    })
    export class DelayedInputDirective implements OnInit,OnDestroy{
      // 声明的 destroy$,配合 takeUntil 运算符一起使用,当指令销毁时,取消订阅
      private destroy$ = new Subject<void>();
      // debounce 配合timer 使用 500ms发出一个值
      @Input() delayTime = 500;
      @Output() delayedInput = new EventEmitter<Event>();
      // 拿到DOM
      constructor(private elementRef: ElementRef<HTMLInputElement>) {
      }
    
      ngOnInit() :void{
        fromEvent(this.elementRef.nativeElement,'input').pipe(
          debounce(()=>timer(this.delayTime)),
          distinctUntilChanged(null,
            (event:Event)=>(event.target as HTMLInputElement).value
            ),
          takeUntil(this.destroy$)
        ).subscribe(e=>this.delayedInput.emit(e))
      }
    
      ngOnDestroy() {
        this.destroy$.next();
      }
    }
    

    使用

      <input type="text" appDelayedInput [delayTime]="600" (delayedInput)="search($event)">
    
     search(event: Event) {
        console.log((event.target as HTMLInputElement).value);
      }
    

    rxjs publish() 冷热处理

     let a = interval(1000).pipe(
          tap(v => console.log('打印下'+v)),
          take(5),
          // 冻住
          publish()
        ) as ConnectableObservable<number>
    
    
        a.subscribe(res => {
          console.log(res);
        }, err => {
    
        }, () => {
          console.log('再见');
        });
        // 解除
          a.connect();
    
    // 打印下0
    // 0
    // 打印下1
    // 1
    // 打印下2
    // 2
    // 打印下3
    // 3
    // 打印下4
    // 4
    // 再见
    

    rxjs delayWhen

     of(10).pipe(delayWhen(_=>timer(1000))).subscribe(res=>{
          console.log(res);
        })
        // 延迟传递值, 传递的参数是一个函数,这种方法好像比较实用
    

    合并

     let a=interval(1000).pipe(take(4))
     let b=interval(1000).pipe(take(2))
    

    zip

        zip(a,b).subscribe(console.log)
    // [ 0, 0]
    // [ 1, 1]
    

    最小分母数

    merge

        merge(a,b).subscribe(console.log)
    // 0 两次
    // 1 两次
    // 1
    // 2
    // 3
    

    concat

        concat(a,b).subscribe(console.log)
    // 0
    // 1
    // 2
    // 3
    // 0 
    // 1
    

    rxjs 运算

    // 观察每次状态的改变
    of(1,2,3,4,5).pipe(scan((acc,val)=>acc+val,0)).subscribe(console.log)
        // 1
        // 3
        // 6
        // 10
        // 15
    // 计算点击的次数
    fromEvent(this.ccc.nativeElement,'click').pipe(scan((acc,val)=>++acc,0)).subscribe(console.log)
    
    of(1,2,3,4,5).pipe(max()).subscribe(console.log)
    // 5
    of(1,2,3,4,5).pipe(min()).subscribe(console.log)
    // 1    
    of(1,2,3,4,5).pipe(reduce((acc,val)=>acc+val)).subscribe(console.log)
    // 15
    of({ name : 'chris' },{ age : 11 }).pipe(
          reduce((acc,curr) => ({ ...acc, ...curr}))
        ).subscribe(console.log)
        // {name: "chris", age: 11}
    

    rxjs buffer缓冲

      interval(200).pipe(
          buffer(timer(1000))
        ).subscribe(console.log)
    // [0,1,2,3]
    //值发生一次
    
    interval(1000).pipe(
          buffer(interval(4000))
        ).subscribe(console.log)
    // [0, 1, 2]
    // [3, 4, 5, 6]
    //  [7, 8, 9, 10]
    // bufferWhen 参数函数 可以用数组长度看相隔多少s点击一次
     interval(1000).pipe(
          bufferWhen(() => fromEvent(this.ccc.nativeElement, 'click'))
        ).subscribe(console.log);
    

    buferCount

    收集缓冲区并在指定数量的值后,作为数组发出

       const src$ = merge(
          of(1).pipe(delay(1000)),
          of(2).pipe(delay(4000)),
          of(3).pipe(delay(5000)),
        );
        src$.pipe(
          bufferCount(3)
        ).subscribe(console.log)
    
    =============
    interval(1000).pipe(
          bufferCount(3)
        ).subscribe(console.log)
    // [0,1,2]
    // [3,4,5]
    // [6,7,8]
    
  • 相关阅读:
    C++ 函数设计原则
    C++ 转换函数搭配友元函数
    C++ 自动转换和强制类型转换(用户自定义类类型)
    C++ rand函数
    C++ 状态成员
    C++ 友元函数
    C++ 运算符重载
    RabbitMQ的简单应用
    Python的正则表达式
    Python的应用小案例
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/13522129.html
Copyright © 2011-2022 走看看