我将一段代码从Session迁移到ReactiveDict。经过一些调试后,发现在向字典中添加{ key : value }对时,ReactiveDict没有触发任何重新计算事件。
var selected = new ReactiveDict()
Meteor.autorun(function() {
for (var k in selected.keys)
console.log("reactiveDict", k, " : ", selected.get(k))
})
Meteor.setTimeout(function () { selected.set('test', true) }, 1000)
Meteor.setTimeout(function () { selected.set('test', false) }, 2000)
Meteor.setTimeout(function () { selected.set('test', true) }, 3000)
Meteor.setTimeout(function () { selected.set('test', false) }, 4000)
那段代码没有输出任何内容,而以下代码可以正常工作。
Meteor.autorun(function() {
for (var k in Session.keys)
console.log("session", k, Session.get(k))
})
Session.set('test', true)
它会打印“session test true”(会话在客户端更新时保存,因此需要确保从新环境开始测试才有效)
我的理解是ReactiveDict是Session的替代品(实际上是将Session的代码制作成一个包)。但在这种情况下,它们的行为非常不同。
我找到的唯一解决方法是使用已存在的人工变量强制触发反应。
var selected2 = new ReactiveDict()
selected2.set('workaround', false)
Meteor.autorun(function() {
for (var k in selected2.keys)
{
var v = selected2.get(k)
if (k != "workaround") console.log("selected2", k, " : ", v)
}
})
var selected2_set = function (key, value) {
var w = (selected2.keys[key] == undefined)
selected2.set(key, value)
if (w) {
selected2.set('workaround', true)
selected2.set('workaround', false)
}
}
Meteor.setTimeout(function () { selected2_set('test', true) }, 1000)
Meteor.setTimeout(function () { selected2_set('test', false) }, 2000)
Meteor.setTimeout(function () { selected2_set('test', true) }, 3000)
打印“selected2 test: true”,然后是false,再是true
我的问题是:
- ReactiveDict的观察行为是特性还是bug?
- 有没有更好的解决方法?
唯一我能想到的“改进”解决方法是允许'workaround'在true和false之间交替,但这会导致其他类型的问题,比如无法仅查找true值进行迭代。
此外,必须小心不要将'workaround'过滤掉,否则重新计算就无法正确触发。例如,autorun中的以下更改不起作用,因为get('workaround')永远不会运行。
if (k != "workaround") console.log("selected2", k, " : ", selected2.get(k))