2017-01-30 2 views
14

Я пытаюсь позвонить в службу при вводе событий ввода.Как получить услугу debounce при событии ввода keyup в angular2 с rxjs

HTML-

<input placeholder="enter name" (keyup)='onKeyUp($event)'> 

Ниже onKeyUp() функции

onKeyUp(event) { 
    let observable = Observable.fromEvent(event.target, 'keyup') 
     .map(value => event.target.value) 
     .debounceTime(1000) 
     .distinctUntilChanged() 
     .flatMap((search) => { 
      // call the service 
     }); 
    observable.subscribe((data) => { 
     // data 
    }); 
} 

Он был найден на вкладке сетевого браузера, что он звонит функцию ключей на каждом ключевых вверх (как это и должно быть сделано), но то, что я пытаюсь достичь, - это время отладки 1сек между каждым вызовом службы. Кроме того, событие срабатывает, если я перемещаю стрелку.

plunkr link

+0

Specify RxJS версию, потому что версии 4 и 5 имеют кучу различий – DDRamone

+0

Это должно быть RxJS 5, потому что он использует Angular2. – martin

+1

Что у вас сейчас есть, так что вы просто не знаете, как позвонить в службу или что? – martin

ответ

24

Так что цепь действительно правильно, но проблема заключается в том, что вы создаете Наблюдаемая и подписаться на него на каждом keyup случае. Вот почему он печатает одно и то же значение несколько раз. Просто несколько подписей, которые вы не хотите делать.

Там вы, очевидно, больше способов сделать это правильно, например:

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <input type="text" (keyup)='keyUp.next($event)'> 
    </div> 
    `, 
}) 
export class App { 
    name:string; 

    public keyUp = new Subject<string>(); 

    constructor() { 
    const subscription = this.keyUp 
     .map(event => event.target.value) 
     .debounceTime(1000) 
     .distinctUntilChanged() 
     .flatMap(search => Observable.of(search).delay(500)) 
     .subscribe(console.log); 
    } 
} 

просмотреть обновленную демо: http://plnkr.co/edit/mAMlgycTcvrYf7509DOP

+1

Это работает, но немного вводит в заблуждение. keyUp не относится к типу Subject . Если вы хотите, чтобы Subject вам нужно указать в input '(keyup) = 'keyUp.next ($ event.target.value)'' –

0

Ну, вот основной debouncer.

ngOnInit () { 
     let inputBox = this.myInput.nativeElement; 
     let displayDiv = this.myDisplay.nativeElement; 

     let source = Rx.Observable.fromEvent (inputBox, 'keyup') 
      .map ((x) => { return x.currentTarget.value; }) 
      .debounce ((x) => { return Rx.Observable.timer (1000); }); 

     source.subscribe (
      (x) => { displayDiv.innerText = x; }, 
      (err) => { console.error ('Error: %s', err) }, 
      () => {}); 
    } 
} 

Если вы настроили два указанных вида детей (вход и дисплей), вы увидите работу по отказу. Не уверен, что это не делает ничего, что вы делаете, но эта базовая форма (насколько мне известно) является простым способом отладки, я использую эту начальную точку совсем немного, набор внутреннего текста - это всего лишь образец, он может сделать служебный вызов или что-то еще, что вам нужно для этого.

Смежные вопросы