简体   繁体   中英

How to use “distinct” RxJS operator in Angular 2?

Below is my Angular 2 component code

import { Component , OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/distinct';

@Component({
             selector:'js',
             template: `
                       <input type="text" id="txt" value="">                           `
          })


  export class Js1Component implements OnInit{  

      ngOnInit(){   

         var data = Observable.fromEvent(document.getElementById('txt'),'keypress')
        .distinct()
        .subscribe({
            next: (e) => { console.log(e);}
        });

   }
}

Since I am using "distinct" operator , when user types "Hello" in textbox , I was expecting that only character h , e , l and o will be printed in the console,that is only one "l" will be printed. But instead all the character are printed( hello).

Any idea how the distinct operator needs to be used.

As stated by @estus in the comment, e is an object in your example and not a string. Hence it's different every time (even if the object's keys were all the same, the reference is different).

You can map the event you receive into the pressed key with function event => event.key .

Observable.fromEvent(this.input.nativeElement, 'keypress')
  .map(event => event.key)
  .distinct()
  .subscribe(e => console.log(e)); // logs key pressed

Depending on the use case, you might need the whole event, and not just the letter pressed afterwards. In that case, using the map operator is a bad idea since you lose all other information.

If this is the case, you can supply a function to .distinct operator. By default this is an identity mapping x => x , but you can make it event => event.key . It will then consider items in the stream different if their .key properties are different.

Observable.fromEvent(this.input.nativeElement, 'keypress')
  .distinct(event => event.key)
  .subscribe(e => console.log(e)); // logs whole event (distinct keys)

On the side note, notice how I don't use native DOM API (like getElementById ). You should use @ViewChild decorator instead for grabbing elements from the template. The full Plunker is here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM