Javascript 当从RxJS subscribe回调更改时,复选框选中的属性不更新元素

Javascript 当从RxJS subscribe回调更改时,复选框选中的属性不更新元素,javascript,checkbox,rxjs,observable,behaviorsubject,Javascript,Checkbox,Rxjs,Observable,Behaviorsubject,我发现了一种我无法解释的非常奇怪的行为。我正在使用RxJS根据BehaviorSubject的值更新一组复选框。我不想更改事件处理程序中的checked属性,也不想让浏览器处理它,因此我使用preventDefault并调用next来设置新值。然后,在我的subscribe回调中,我尝试设置输入的checked属性,但它似乎没有效果 运行下面的代码段,并尝试更改任何复选框。请注意,每次记录元素的名称和假定的已选中的值时,这似乎表明一切正常,但输入本身不会改变状态。我添加了额外的样式以使选中的项目

我发现了一种我无法解释的非常奇怪的行为。我正在使用RxJS根据BehaviorSubject的值更新一组复选框。我不想更改事件处理程序中的checked属性,也不想让浏览器处理它,因此我使用
preventDefault
并调用
next
来设置新值。然后,在我的
subscribe
回调中,我尝试设置输入的
checked
属性,但它似乎没有效果

运行下面的代码段,并尝试更改任何复选框。请注意,每次记录元素的名称和假定的
已选中的
值时,这似乎表明一切正常,但输入本身不会改变状态。我添加了额外的样式以使选中的项目更可见

const{BehaviorSubject}=rxjs;
const{distinctUntilChanged}=rxjs.operators;
const$checkbox=Array.from(document.querySelectorAll('input[type=“checkbox”]”);
常量设置={
a:错,
b:是的,
c:错,
d:错,
e:是的,
f:是的,
}
常量源={};
常量观察员={};
$checkbox.forEach(el=>{
常数{name}=el;
el.checked=设置[名称];
sources[名称]=新行为主体(el.选中);
观察者[名称]=源[名称].asObservable().pipe(distinctUntilChanged());
el.addEventListener('click',e=>{
e、 预防默认值();
const{name}=e.target;
源[name]。下一步(!设置[name]);
});
观察员[name]。订阅(值=>{
设置[名称]=值;
el.checked=设置[名称];
console.log(名称、el.name、el.checked、值);
});
})
console.clear()
标签{
显示:内联块;
保证金:3倍;
}
输入:选中+span{
字体大小:粗体;
文字装饰:下划线;
}
选项A
方案B
备选案文C
方案D
选项E
选项F
preventDefault()
将在执行click事件侦听器后恢复值。请看

您可以使用setTimeout(()=>xxx,0)延迟下一个事件循环中的执行,该循环将在
preventDefault
run之后发生

const{
行为主体,
可见的,
推迟
}=rxjs;
常数{
不同的是,
地图,
合并地图
}=rxjs.运算符;
const$checkbox=Array.from(document.querySelectorAll('input[type=“checkbox”]”);
常量设置={
a:错,
b:是的,
c:错,
d:错,
e:是的,
f:是的,
}
常量源={};
常量观察员={};
$checkbox.forEach(el=>{
常数{
名称
}=el;
el.checked=设置[名称];
sources[名称]=新行为主体(el.选中);
观察者[名称]=源[名称].asObservable().pipe(distinctUntilChanged());
el.addEventListener('click',e=>{
常数{
名称
}=e.目标;
源[name]。下一步(!设置[name]);
e、 预防默认值();
});
控制台日志(可观察)
观察者[name]。管道(映射(值=>{
返回setTimeout(()=>{
设置[名称]=值;
el.checked=设置[名称];
console.log(名称、el.name、el.checked、值);
}, 0)
})).subscribe()
})
console.clear()
标签{
显示:内联块;
保证金:3倍;
}
输入:选中+span{
字体大小:粗体;
文字装饰:下划线;
}
选项A
方案B
备选案文C
方案D
选项E
选项F

感谢您提供的解释链接,我不知道这是由preventDefault引起的,但现在它确实有意义了。看来setTimeout毕竟是解决这个问题的最简单方法。