2016-04-02 71 views
1
/** 
* 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()按角度计算按键每秒2 Rxjs

它的工作原理,但我认为可能有错误。

我做excersizes在那里 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的事件。然后事件停止,直到我再次按下按键。 我需要修改什么,所以我每秒都会收到活动?

回答

2

我认为你可以利用缓冲区操作符。它允许缓冲事件并在一段时间后发送它们。然后,您可以将该事件列表映射到其长度。

var source = Observable.fromEvent(document.body, 'keyup'); 

var obs = source 
    .bufferTime(1000).map((clickBuffer) => { 
     return clickBuffer.length; 
    }); 

obs.subscribe((num) => { 
    // Get the number of pressed keys per second 
}); 

请参见以下链接:

+0

不工作对我来说,至少在RxJs 5 - 收到错误:错误:(161,15)TS2345 :类型'()=>可观察<{}>'的参数不可分配给类型为'Observable '的参数。 类型'()=> Observable <{}>'中缺少属性'_isScalar'。 –

+0

找到了如何解决错误 - 传递delayedSource到缓冲区函数。但仍然不能像我想要的那样工作 –

+1

你说得对。你应该使用bufferTime操作符。我相应地更新了我的答案...... –