【发布时间】:2018-08-14 03:09:50
【问题描述】:
我发现了一种我无法解释的非常奇怪的行为。我正在使用 RxJS 根据 BehaviorSubject 的值更新一组复选框。我不想更改事件处理程序中的选中属性,也不想让浏览器处理它,所以我使用preventDefault 并调用next 来设置新值。然后,在我的subscribe 回调中,我尝试设置输入的checked 属性,但它似乎没有效果。
运行下面的 sn-p,并尝试更改任何复选框。请注意,每次记录元素的名称和假定的 checked 值时,这似乎表明一切正常,除了输入本身不会改变状态。我添加了额外的样式以使选中的项目更加明显。
const { BehaviorSubject } = rxjs;
const { distinctUntilChanged } = rxjs.operators;
const $checkboxes = Array.from(document.querySelectorAll('input[type="checkbox"]'));
const settings = {
a: false,
b: true,
c: false,
d: false,
e: true,
f: true,
}
const sources = {};
const observers = {};
$checkboxes.forEach(el => {
const { name } = el;
el.checked = settings[name];
sources[name] = new BehaviorSubject(el.checked);
observers[name] = sources[name].asObservable().pipe(distinctUntilChanged());
el.addEventListener('click', e => {
e.preventDefault();
const { name } = e.target;
sources[name].next(!settings[name]);
});
observers[name].subscribe(value => {
settings[name] = value;
el.checked = settings[name];
console.log(name, el.name, el.checked, value);
});
})
console.clear();
label {
display: inline-block;
margin: 3px;
}
input:checked + span {
font-weight: bold;
text-decoration: underline;
}
<label><input type="checkbox" name="a"> <span>Option A</span></label>
<label><input type="checkbox" name="b"> <span>Option B</span></label>
<label><input type="checkbox" name="c"> <span>Option C</span></label>
<label><input type="checkbox" name="d"> <span>Option D</span></label>
<label><input type="checkbox" name="e"> <span>Option E</span></label>
<label><input type="checkbox" name="f"> <span>Option F</span></label>
<script src="https://unpkg.com/rxjs@6.2.2/bundles/rxjs.umd.min.js"></script>
当然,这只是一个 MCVE,我的实际代码分为多个文件和类。我在想这可能与变量传递的方式有关,但请注意 el.name 和 name 在记录的值中是相同的,这意味着 el 应该是与以前相同的元素。
将el.checked 的作业包装在setTimeout 中似乎可以解决问题,但这样做几乎不是正确的解决方案。我想知道是什么导致了这种行为,以及如何在没有黑客攻击的情况下使这种设置工作。
【问题讨论】:
标签: javascript checkbox rxjs observable behaviorsubject