angular4学习笔记(第八章 响应式编程篇)

1.Rxjs基础知识

  • 基本概念
    1. Observable (可观察对象): 表示一个概念,这个概念是一个可调用的未来值或事件的集合。
    2. Observer (观察者): 一个回调函数的集合,它知道如何去监听由 Observable 提供的值。
    3. Subscription (订阅): 表示 Observable 的执行,主要用于取消 Observable 的执行。
    4. Operators (操作符): 采用函数式编程风格的纯函数 (pure function),使用像 map、filter、concat、flatMap 等这样的操作符来处理集合。
    5. Subject (主体): 相当于 EventEmitter,并且是将值或事件多路推送给多个 Observer 的唯一方式。
    6. Schedulers (调度器): 用来控制并发并且是中央集权的调度员,允许我们在发生计算时进行协调,例如 setTimeout 或 requestAnimationFrame 或其他。
  • RXJS6的变化
    1. 引入变化angular4学习笔记(第八章 响应式编程篇)_第1张图片angular4学习笔记(第八章 响应式编程篇)_第2张图片angular4学习笔记(第八章 响应式编程篇)_第3张图片angular4学习笔记(第八章 响应式编程篇)_第4张图片
    2. 总而言之: 类似于创建之类的用的API都是从rxjs引入的,类似于map 之类的操作都是从rxjs/operators引入的
    3. 如果项目升级不能马上更改完全部相关代码的可安装以下东西,可以暂时不用改代码,可以一点点地改,直到改完后吧这个包卸掉,但是对于rxjs6的rename的operator无效,所以,如果有用到rename的API,必须手动修改
      npm install --save rxjs-compat
    4. 具体例子(按钮点击事件)
      import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
      import { fromEvent, from } from 'rxjs';
      import { filter, map } from 'rxjs/operators';
      // import "rxjs/add/Observable/fromEvent";  RXJS6之前的引入方式
      // import "rxjs/add/operator/map";  RXJS6之前的引入方式
      
      @Component({
        selector: 'app-rxjs-demo',
        templateUrl: './rxjs-demo.component.html',
        styleUrls: ['./rxjs-demo.component.css']
      })
      export class RxjsDemoComponent implements OnInit {
      
        @ViewChild('click')
        button: ElementRef
      
        constructor() { }
      
        ngOnInit() {
      
        }
      
        clickEvent() {
      
          // 注册并发送事件(RXJS6),静态方法直接调用就可以了
          fromEvent(this.button.nativeElement, 'click')
            .subscribe(
              () => console.log('Clicked!'),
              err => console.error(err),
              () => console.log("结束了")
            );
      
          // 注册并发送事件(RXJS6之前)
          // Observable.fromEvent(this.button.nativeElement, 'click')
          // .subscribe(
          //   () => console.log('Clicked!'),
          //   err => console.error(err),
          //   () => console.log("结束了")
          // );
      
          // 注册并发送值(RXJS6)
          from([1, 2, 3, 4]).pipe(
            filter(e => e % 2 == 0),
            map(e => e * e)
          )
            .subscribe(
              e => console.log(e),  
              err => console.error(err),
              () => console.log("结束了")
      
            )
      
          // 注册并发送值(RXJS6之前)
          // Observable.from([1, 2, 3, 4])
          //   .filter(e => e % 2 == 0)
          //   .map(e => e * e)
          //   .subscribe(
          //     e => console.log(e),
          //     err => console.error(err),
          //     () => console.log("结束了")
          //   )
      
        }
      
      
      
      
      
      }
      
    5. 案例分析

      1. 在上面的发送事件例子中

      2. Subscription(订阅):

        subscribe(

        () => console.log('Clicked!'),

        err => console.error(err),

        () => console.log("结束了")

        );

      3. Subject(主体): (this.button.nativeElement, 'click')

      4. Observable(可观察对象) :fromEvent(返回的还是一个Observable)。

      5. Observer(观察者): Subscribe内部的函数就是观察者。

        () => console.log('Clicked!'),  事件成功的回调函数

        err => console.error(err),  事件出现错误的回调函数

        () => console.log("结束了")  事件结束的回调函数(要么成功要么失败

  • 拉取与推送(转载)

    拉取和推送是两种不同的协议,用来描述数据生产者 (Producer)如何与数据消费者 (Consumer)如何进行通信的。
    什么是拉取? - 在拉取体系中,由消费者来决定何时从生产者那接收数据。生产者本身不知道数据是何时交付到消费者手中的。
    什么是推送? - 在推送体系中,由生产者来决定何时把数据发送给消费者。消费者本身不知道何时会接收到数据。在当今的 

    JavaScript 世界中,Promises 是最常见的推送体系类型。Promise(生产者) 将一个解析过的值传递给已注册的回调函数(消费者),但不同于函数的是,由 Promise 来决定何时把值“推送”给回调函数。

    RxJS 引入了 Observables,一个新的 JavaScript 推送体系。Observable 是多个值的生产者,并将值“推送”给观察者(消费者)。
    Function 是惰性的评估运算,调用时会同步地返回一个单一值。
    Generator 是惰性的评估运算,调用时会同步地返回零到(有可能的)无限多个值。返回一个iterators,每次的调用会返回一个值。
    Promise 是最终可能(或可能不)返回单个值的运算。通过resolve决定值的返回。
    Observable 是惰性的评估运算,它可以从它被调用的时刻起同步或异步地返回零到(有可能的)无限多个值。

    这里的惰性的意义是说,需要调用者去调用才会触发结果的返回。上面的方式promise来说,对于回调函数then是在promise resolve值之后才会调用,否则永远不会调用,不管你的then是否存在,其他几种的话,只要调用就已经会返回值了,不管你何时调用,都会有相应的返回值,而不像promise可以决定这个值什么时候返回,是否返回。

2.angular中的响应式编程

  • 响应式编程就是:就是异步数据流编程
  • 案例:现在有个搜素框,我输入东西后就开始进行搜索。我想搜索Alibaba,当我输入A的时候就会触发keyup事件去服务器搜索,当我输入AL的时候也会去服务器搜索。这不是我们想要的。我们想输入完Alibaba后去搜索。这里可以设置一个时间间隔,在这个时间间隔内没有再输入东西的时候就去服务器搜索。这个功能用传统的JavaScript实现起来比较麻烦。
  • 需要在app,module.ts中引入ReactiveFormsModule
  • 创建搜索框
    
    

     

  • 实现响应式功能
    import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
    import { FormControl } from '@angular/forms';
    import { debounceTime } from 'rxjs/operators';
    
    @Component({
      selector: 'app-rxjs-ng',
      templateUrl: './rxjs-ng.component.html',
      styleUrls: ['./rxjs-ng.component.css']
    })
    export class RxjsNgComponent implements OnInit {
    
      searchInput: FormControl = new FormControl();
      constructor() {
        this.searchInput.valueChanges.pipe(
          debounceTime(500)//设置为500毫秒
        )
          .subscribe(stockCode => this.getInputValue(stockCode));//stockCode就是用户输入的值
      }
    
      ngOnInit() {
      }
    
      getInputValue(value: string) {
        console.log(value);
      }
    }
    

3.通过响应式编程与管道为在线竞拍提供一个商品过滤功能

  • 为商品组件添加一个商品搜索输入框
    import { Component, OnInit } from '@angular/core';
    import { ProductService, Products } from 'src/shared/product.service';
    import { FormControl } from '@angular/forms';
    
    @Component({
      selector: 'app-product',
      templateUrl: './product.component.html',
      styleUrls: ['./product.component.css']
    })
    export class ProductComponent implements OnInit {
    
      // 声明变量接收商品信息
      public products: Products[];
      // 定义关键词formControl
      public titleFilter: FormControl = new FormControl();
      // 声明关键词变量
      private keyword: string;
      // 注入商品服务
      constructor(private _ProductService: ProductService) {
        // 监听商品输入框值变化
        this.titleFilter.valueChanges
          .subscribe(
            value => this.keyword = value
          );
      }
    
      ngOnInit() {
        // 使用商品服务的getProducts()方法获取商品信息
        this.products = this._ProductService.getProducts();
      }
    
    }
    
    

     

  • 自定义商品过滤管道(ng g p pipe/filter)
    import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({
      name: 'filter'
    })
    export class FilterPipe implements PipeTransform {
    
      // filterField  :  根据商品什么字段过滤
      // keyword      :  商品关键词
      transform(list: any[], filterField?: string, keyword?: string): any {
        // 判断是否输入关键词
        if (!filterField || !keyword) {
          return list;
        }
        // 返回与关键词相对应的值
        return list.filter(item => {
          const filedValue = item[filterField];
          return filedValue.indexOf(keyword) >= 0;
        });
      }
    
    }
    

     

  • 在商品组件中使用管道

    ¥{{product.price}}

    {{product.name}}

    {{product.desc}}

    {{product.rating | number: '1.1-1'}} 星

4.效果展示

你可能感兴趣的:(日常笔记,angular)