Angular 在自动保存场景中,以何种顺序使用哪些rxjs运算符
我想用RxJS在Angular中自动保存一个表单。 表单更改时将发出一个事件 这是一个场景:Angular 在自动保存场景中,以何种顺序使用哪些rxjs运算符,angular,rxjs,Angular,Rxjs,我想用RxJS在Angular中自动保存一个表单。 表单更改时将发出一个事件 这是一个场景: 当表单输出已更改,但在接下来的10秒内不再更改时,它应发出一个保存事件 只有当窗体每10秒更改一次以上(至少30秒)时,它才应发出保存事件 对于第一个,我可以使用去盎司,但如何将其与第二个规则结合起来?您需要将流分成两个流 const source=fromEvent(document.getElementById(“text”),“input”); 来源 .管道(去BounceTime(10*1000
对于第一个,我可以使用去盎司,但如何将其与第二个规则结合起来?您需要将流分成两个流
const source=fromEvent(document.getElementById(“text”),“input”);
来源
.管道(去BounceTime(10*1000))
.subscribe(()=>console.log(“键入后保存”);
来源
.烟斗(
审核时间(10*1000)
)
.subscribe(()=>console.log(“键入时保存”);
在第一种情况下,如您所述,使用debounceTime值将在用户完成编辑表单/输入10秒后发出。在第二种情况下,auditTime每10秒将检查是否有任何新值。如果有,则会发出值。在回调中,您可以重用负责从表单保存数据的相同函数。
您可以在stackblitz的演示中尝试:
我只是将演示中的时间改为1秒,这样在控制台中更容易检查结果
旁注:
这是简单的JS演示。如果开发Angular应用程序,应该避免使用getElementById获取元素。不要使用直接引用模板:
编辑:
根据OP评论,我对实现做了一点修改。我合并了两个观察值,并使用distinctUntilChanged操作符避免两次发出相同的值。stackblitz中的演示也发生了变化
const-postertyping=source.pipe(debounceTime(1000));
const whileTyping=source.pipe(审核时间(1000));
合并(同时键入,后键入)
.pipe(distinctUntilChanged())
.subscribe(console.log);
这个问题有点棘手,但是将去BounceTime
和节流时间
适当组合可以解决问题:
const s = new Subject();
s.subscribe();
const saveEvery3sSubject = new Subject();
saveEvery3sSubject.subscribe();
const saveEvery3s$ = saveEvery3sSubject.pipe(
throttleTime(3000),
mapTo('saving after 3000 ms'),
startWith(null)
);
const debounce$ = s.pipe(
tap(r => {
saveEvery3sSubject.next(r); // this step starts the 3000ms timer
}),
debounceTime(1000),
startWith(null),
);
// combining them both so the saving will occur on debounce or after 3000ms
const result$ = combineLatest([debounce$, saveEvery3s$]).pipe(
filter(([d, s]) => s !== null)
)
// first 5 values will be debounced forever because 500 < 1000(debounceTime)
interval(500).pipe(
take(5)
)
.subscribe(i => {
s.next('form changed #' + i);
})
// these values will be emitted correctly one by one
timer(9000, 1100).pipe(
take(20)
)
.subscribe(i => {
s.next('after pause #' + i);
})
result$.subscribe();
const s=新主题();
s、 订阅();
const saveevery3subject=新主题();
SaveEvery3Subject.subscribe();
const saveEvery3s$=saveEvery3sSubject.pipe(
节流时间(3000),
映射到(“3000毫秒后保存”),
startWith(空)
);
const debounce$=s.pipe(
点击(r=>{
saveEvery3sSubject.next(r);//此步骤启动3000ms计时器
}),
去BounceTime(1000),
startWith(空),
);
//将两者结合在一起,以便在去盎司时或3000毫秒后进行保存
const result$=CombineTest([debounce$,saveEvery3s$])。管道(
过滤器(([d,s])=>s!==null)
)
//前5个值将永远去噪,因为500<1000(去噪时间)
间隔(500)。管道(
采取(5)
)
.订阅(i=>{
s、 下一步(‘形式改变#’+i);
})
//这些值将一个接一个地正确发出
计时器(9000、1100)。管道(
采取(20)
)
.订阅(i=>{
s、 next(‘暂停后#’+i);
})
结果$.subscribe();
使用附加主题是必要的,因为您操作两个独立的时间框架:
- debounceTime-更改表单并发出更改时
- throttleTime-确保表单每30秒保存一次,而不考虑取消公告的输入(如果您比取消公告的时间快,那么这些值根本不会发出!)
startWith(null)
-这是combinelatetest
发出第一个值所必需的
这一解决方案正在发挥作用:
您能更清楚地解释第二个指针吗?您能分享您已经尝试过的代码以及您遇到的问题吗?谢谢,有一个问题:如果我加载stackblitz并键入一个字符,它将保存两次,一次来自源代码1,另一次来自源代码2。最理想的是一个。我想我需要清除audittime事件,无论何时解盎司时间发出?我能做到吗?当然有可能。我在answer和StackBlitzThank中更改了实现,并对其进行了测试,这正是我所需要的,清晰而简单