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

本文详细介绍了RxJS的基础知识,包括Observable、Observer、Subscription和操作符等概念,探讨了Angular中的响应式编程及其在事件处理中的应用,如设置搜索延迟触发。此外,还展示了如何通过响应式编程和管道实现在线竞拍的商品过滤功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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. 引入变化
    2. 总而言之: 类似于创建之类的用的API都是从rxjs引入的,类似于map 之类的操作都是从rxjs/operators引入的
    3. 如果项目升级不能马上更改完全部相关代码的可安装以下东西,可以暂时不用改代码,可以一点点地改,直到改完后吧这个包卸掉,但是对于rxjs6的rename的operator无效,所以,如果有用到rename的API,必须手动修改
      npm install --save rxjs-compat
    4. 具体例子(按钮点击事件)
      <button #click type="button" (click)="clickEvent()">点击</button>
      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
  • 创建搜索框
    <input [formControl]="searchInput">
    

     

  • 实现响应式功能
    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.通过响应式编程与管道为在线竞拍提供一个商品过滤功能

  • 为商品组件添加一个商品搜索输入框
    <div class="row">
      <div class="col-sm-12">
        <div class="form-group">
          <input class="form-control" placeholder="请输入商品名称"
          [formControl]="titleFilter">
        </div>
      </div>
    </div>
    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;
        });
      }
    
    }
    

     

  • 在商品组件中使用管道
    <div class="row">
      <div class="col-sm-12">
        <div class="form-group">
          <input class="form-control" placeholder="请输入商品名称"
          [formControl]="titleFilter">
        </div>
      </div>
    </div>
    
    <div class="row">
      <!-- 引入商品过滤管道,根据商品名称过滤商品 -->
      <div class="col-lg-4 col-md-4 col-xs-12" *ngFor="let product of products | filter:'name':keyword">
        <div class="thumbnail">
          <img src={{product.img}} alt="">
          <div class="caption">
            <h3 class="pull-right">¥{{product.price}}</h3>
            <!-- 点击商品名称跳转到商品详情页,传递两个参数id,name -->
            <a [routerLink]="[ '/detialproduct', product.id , product.name ]">
              <h3>{{product.name}}</h3>
            </a>
            <span class="product-desc">{{product.desc}}</span>
            <p>
              <!--星级评价的rating属性由产品的rating属性传进去-->
              <app-stars [rating]="product.rating"></app-stars>
              <span> {{product.rating | number: '1.1-1'}} 星</span>
            </p>
          </div>
        </div>
      </div>
    </div>
    

4.效果展示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值