gpt4 book ai didi

javascript - Meteor ReactiveDict 不会在第一次插入时触发事件

转载 作者:数据小太阳 更新时间:2023-10-29 05:33:08 24 4
gpt4 key购买 nike

我将一段代码从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”( session 在客户端更新时保存,因此需要确保从一个新的环境开始以使测试有效)

我的理解是 ReactiveDict 是 Session 的直接替代品(实际上它是将 Session 的代码提供到一个包中)。但在这种情况下,它们的行为非常不同。

我发现的唯一解决方法是用一个已经存在的人工变量强制触发 react

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 行为是特性还是错误?
  • 有更好的解决方法吗?

我想到的变通办法的唯一“改进”是允许“变通办法”在 true 和 false 之间交替,但这会产生其他类型的问题,例如无法迭代只寻找真值。

此外,必须小心不要过滤掉“变通方法”,因为这样就不会正确触发重新计算。例如,自动运行中的以下更改不起作用,因为 get('workaround') 永远不会运行。

if (k != "workaround") console.log("selected2", k, " : ", selected2.get(k))

最佳答案

keys 只是 ReactiveDict 的一个属性,并没有注册响应式依赖项,因此这种行为是意料之中的。在current implementation ( meteor v1.1)没有一种简单的方法可以实现您正在寻找的东西。

upcoming version 中, all 将建立对所有键的响应依赖,因此这将起作用:

Tracker.autorun(function() {
_.each(selected.all(), function(value, key) {
console.log(key + ":" + value);
});
});

如果你现在想使用那个版本,你可以将源代码下载到一个名为 lib/reactive-dict2.js 的文件中,并将对 ReactiveDict 的任何引用替换为 ReactiveDict2(当前为第 19 和 43 行 - 请注意,这很关键,否则您应用的其他部分可能会中断)。然后你可以这样做来使用它:

var selected2 = new ReactiveDict2()

上面的代码应该可以工作。

关于javascript - Meteor ReactiveDict 不会在第一次插入时触发事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30091091/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com