头图

I developed a simple Angular application to demonstrate the usage of this rxjs Operator at the following address:

https://jerry-combine.stackblitz.io/

Where limit controls the number of list elements displayed, and offset controls the index of the displayed elements:

For example, when I change the offset to 1, the displayed elements start at ivysaur:

First, I designed a form form, which contains two input controls, which maintain limit and offset respectively:

<form>
    <mat-form-field class="example-full-width">
      <input matInput placeholder="Limit" [formControl]="limitControl" type="number">
    </mat-form-field>
    <mat-form-field class="example-full-width">
      <input matInput placeholder="Offset" [formControl]="offsetControl" type="number">
    </mat-form-field>
  </form>

limitControl and offsetControl are the two public properties I defined in the component:

Data source for limit$: from limitControl.valueChanges.

 const limit$ = this.limitControl.valueChanges
      .pipe(
        startWith(this.limitControl.value),
        // Needed to fix a bug where inputs with type number emit twice
        // https://github.com/angular/angular/issues/12540
        distinctUntilChanged(),
      );

Note that a distinctUntilChanged is used here, which means that if the value of limit$ has not changed, the data will not be emitted downstream.

Data source for pokemon$:

this.pokemon$ = combineLatest(limit$, offset$)
      .pipe(
        map(data => ({limit: data[0], offset: data[1]})),
        switchMap(data => this.pokemonService.getPokemon(data.limit, data.offset)),
        map((response: {results: Pokemon[]}) => response.results),
      );

Note the data in line 62 of the code, the data structure is an array, the first element is the value contained in limit$, and the second element is the value contained in offset$:

After these two values are processed by map, they are delivered to the service pokemonService.

Finally, the Response returned by the service is expanded through ngFor and displayed as a list.

The final rendered list data is shown in the following figure:

https://pokeapi.co/api/v2/pokemon/?offset=7&limit=6 This api can be used for learning purposes on the public network:

Here's a little problem: every time I change the limit value in the browser:

The valueChanges event of the form control fires twice:

This is a known issue with the Angular framework:

https://github.com/angular/angular/issues/12540

In order to use the formControl directive, we need to import the following module in the appmodule:

import { FormsModule, ReactiveFormsModule } from '@angular/forms';

The elements mat-form-field, etc. used in the app component template are from the Angular material design module:

import { MatInputModule } from '@angular/material/input';
import { MatCardModule } from '@angular/material/card';
import { MatTableModule } from '@angular/material/table';
import { MatButtonModule } from '@angular/material/button';

As shown below:

These dependencies need to be explicitly defined in package.json:

More Jerry's original articles, all in: "Wang Zixi":


注销
1k 声望1.6k 粉丝

invalid