RxJS - 缓冲唯一值并在x秒内没有发出其他值时发出?

时间:2018-05-08 09:58:38

标签: javascript rxjs rxjs5 reactive-extensions-js

用户在表单中键入值,每次用户编辑特定字段时都会发出一个事件,其值为他们编辑的字段。

例如,用户在描述字段中键入3次,然后在名称字段中键入两次,将显示为

  

"描述" => "描述" => "描述" => "名称" => "名称" => ...

我希望缓冲唯一值,并在用户停止输入 x 秒数时将其作为数组发出。值可能再次出现在不同的缓冲区窗口中。

基本上,这是为了跟踪用户停止输入时更新的字段,并与服务器通信以保存编辑后的值。

到目前为止,我有这个 3000毫秒,而且它在缓冲时不会防止重复,而是我们"重复删除"之后是阵列。

   this.update$
      .bufferTime(3000)
      .filter(buffer => buffer.length > 0)
      .map(buffer => [...new Set(buffer)])
      .subscribe(x => console.log(x));

所以它应该监听,直到发出一个值然后缓冲唯一,直到 x 秒发出更多值,然后发出缓冲区并重复。怎么能实现这个目标呢?

2 个答案:

答案 0 :(得分:1)

也许我的问题不够清楚,无论如何我都设法解决了这个问题:(如果它能帮助其他人)

当流静默3秒钟时让缓冲区只发出 ,每次用户输入内容时都会启动一个新的计时器(css上发出的事件),然后使用{ {1}}取消上一个。

span.own3 {
  background: #FFFFFF;
  opacity: 1;
  border: 1px solid #DCDCDC;
  color: #000000;
  font-size: 12px;
  height: auto;
  width: auto;
  min-width: 300px;
  letter-spacing: 1px;
  line-height: 14px;
  position: absolute;
  text-align: justify;
  top: 100%; // Changed to percentage instead of px
  left: 0px;
  display: none;
  padding: 2px 5px;
  font-family: "Helvetica Neue", Arial, sans-serif;
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1), 0 3px 10px 0 rgba(0, 0, 0, 0.09);
}

hover.own2 {
  position: relative;
}

hover.own2:hover span {
  display: block;
}

.table.hoverstatus>tbody>tr:first-child>th {
  border: none;
}
.dd-label {
  padding: 10px 0;
  display: inline-block;
}

然后为了使缓冲区本身是唯一的而不是必须手动重复数据删除,我必须创建一个自定义运算符<div style="padding:15px;"> <div class="shadow p-3 mb-5 bg-white rounded table-responsive" style="border: 1px solid #F0F0F0;font-family: 'Poppins', sans-serif;font-size:14px;"> <table id="example" class="table table-striped" width="100%"> <thead> <tr> <th>Feeling</th> <th>Day</th> </tr> </thead> <tbody> <tr> <td> Super </td> <td>1</td> </tr> <tr> <td> <hover class="own2"> <!-- wrap this label in a span tag --> <span class="dd-label">Great</span> <!-- span tag ends --> <span class="own3"><table class="table hoverstatus" id="innertable"><tr><th>Row1 Col1</th><th>Row1 Col2</th><th>Row1 Col3</th></tr><tr><td>Row2 Col1</td><td>Row2 Col2</td><td>Row2 Col3</td></tr></table></span></hover> </td> <td>2</td> </tr> </tbody> </table> </div> </div>

update$
switchMap

答案 1 :(得分:1)

这可能是替代版本:

const { Observable } = Rx;

const log = (prefix) => (...args) => { console.log(prefix, ...args); };

const inputs = document.querySelectorAll('input');

const updates$ = Observable
  .fromEvent(inputs, 'input')
  .pluck('target', 'id')
;

// wait x ms after last update
const flush$ = updates$.debounceTime(3000);

const buffered$ = updates$
  // use `distinct` without `keySelector`, but reset with flush$
  .distinct(null, flush$)
  
  // flush the buffer using flush$ as `notifier`
  .buffer(flush$)
;

buffered$.subscribe(log('buffered$ =>'));
<script src="https://unpkg.com/@reactivex/rxjs@^5/dist/global/Rx.min.js"></script>

<div><input type="text" placeholder="foo" id="input.foo"></div>
<div><input type="text" placeholder="bar" id="input.bar"></div>
<div><input type="text" placeholder="baz" id="input.baz"></div>