/**
* Created by darius on 02/04/16.
*/
import { Component } from 'angular2/core';
import { Observable } from 'rxjs/Rx';
@Component({
styles: [ require('../../style.css') ],
selector: 'keypresses-per-second',
template: `
<div class="block">
<input type="text" (keypress)="onKeypress($event)">
{{keypresses}} <br>
<input type="text" (keypress)="onKeypressReact($event)">
{{keypressesReactive}}
</div>
`
})
export class KeypressesPerSecond {
ngOnInit() {
this.nonReactive();
this.reactiveWay();
}
// not reactive
keypresses = '';
counter = 0;
secondsPassed = 0;
nonReactive(){
var self = this;
var int = setInterval(function(){
console.log(self.counter, 'counter in non reactive')
self.keypresses += self.counter + ', ';
self.counter = 0;
self.secondsPassed++
if (self.secondsPassed > 30) {
clearInterval(int);
}
}, 1000);
}
onKeypress($event){
console.log($event.keyCode);
this.counter++;
}
// end not reactive
onKeypressReact() {}
keypressesReactive = '';
reactiveCount = 0;
reactiveWay() {
console.log('reactive way')
const keypressObservable$ = Observable.create(observer => {
// from template
this.onKeypressReact = () => { observer.next('press'); };
});
keypressObservable$.subscribe(function(event) {
self.reactiveCount++;
});
var self = this;
var timer$ = Observable.create(function(observer){
// is subscribed to this observable
var subscribed = true;
var int = setInterval(function() {
if (subscribed) {
observer.next(self.reactiveCount);
self.reactiveCount = 0;
}
if (self.secondsPassed > 30) {
observer.complete();
clearInterval(int)
}
}, 1000);
})
timer$.subscribe(
function (x) {
console.log('Nextzz: %s', x);
self.keypressesReactive += x + ', ';
});
}
}
Я пытался написать реактивный и нереактивный способ счетчика нажатий клавиш. Взгляните на функцию reactiveWay()
это работает, но я думаю, что может быть что-то не так.
Я делал там упражнения http://reactivex.io/learnrx/
и было много маппинга.
Такое ощущение, что мне нужно было сопоставить временное событие с последовательностью ключевых событий, происходящих в секунду. Но не понимаю, как я мог сопоставить их.
Что-то типа
// doing this way we could removed some code from timer$, we just need to get an event
var kps$ = timer$.concatMap(function(time) {
var sum = keypressObservable$.takeUntil(timer$)
.reduce(function (acc, cur) {
return acc + cur;
})
console.log('sum', sum);
return sum;
})
// this works, counts the keypresses, but only when pressing at least 1.
kps$.subscribe(
function (x) {
console.log('kps next', x);
self.keypressesReactive += x + ', ';
});
Как заставить kps$ выдавать 0 сумм, если за секунду не было нажатий клавиш, если я использую kps$?
Обновить
Основываясь на ответе, я сделал это.
var source = Observable.fromEvent(document.body, 'keypress');
var delayedSource = source.delay(1000);
var obs = source
.buffer(delayedSource)
.map((clickBuffer) => {
return clickBuffer.length;
})
Но когда я подписываюсь на obs, я не получаю событие каждую секунду, содержащее значение 0. Когда я нажимаю несколько клавиш в секунду, я получаю количество нажатых клавиш и другое событие 0. И затем события останавливаются, пока я снова не нажму клавиши. Что мне нужно изменить, чтобы я получал событие каждую секунду?