在此JSFiddle中可以看到所有即将跟随的代码。我已经从这个问题中遗漏了 HTML 数据绑定和模板,但它们可以在小提琴中看到。我认为它们与说明问题无关。
介绍
我正在尝试将计算的 observable 链接到我用作 HashMap 的另一个对象。
具有计算的 observable 的对象是HistoryEntry
:
function HistoryEntry(userId, users) {
this.UserId = ko.observable(userId);
this.User = ko.computed(function () {
if (!users[this.UserId()]) return '(' + this.UserId() + ')';
return '(' + this.UserId() + ') ' + users[this.UserId()].Name();
}, this);
}
HistoryEntry
包含一个用作我的UserId
JavaScript 对象中的查找值的 HashMap。users
是对 ViewModel 中包含的此 HashMap 的引用。
HashMap 包含User
由它们的键控的对象UserId
。User
对象如下:
function User(id, name) {
this.Id = ko.observable(id);
this.Name = ko.observable(name);
}
这个想法是计算出的 observableHistoryEntry.User()
将从User
这个 HashMap 中的相应对象中查找名称。
HashMap 与可观察的对象数组一起存储在父 ViewModel 上HistoryEntry
:
function ViewModel() {
this.users = ko.observable({
'16': new User(16, 'Jack'),
'17': new User(17, 'Jill')
});
this.history = ko.observableArray([
new HistoryEntry(16, this.users()),
new HistoryEntry(17, this.users()),
new HistoryEntry(18, this.users())
]);
}
var view = new ViewModel();
ko.applyBindings(view);
问题
正如您在上面看到的,我只创建了两个用户,但我有三个历史条目,每个都指向不同的用户。这些条目之一是指 HashMap 中尚不存在的 User(18)。
对于我的示例,我将 User(16) 的名称从“Jack”更改为“John”并添加 User(18):
setTimeout(function () {
view.users()[16].Name('John');
view.users()[18] = new User(18, 'Bill');
view.users.valueHasMutated();
view.history.valueHasMutated();
}, 1000);
这会正确更新HistoryEntry
具有指向 User(16) 的计算 observable 的。
同样,我希望当我添加 User(18) 时,对 User(18)HistoryEntry
的计算 observable 将使用 User(18) 的名称进行更新。
不幸的是,事实并非如此。
问题
- 我想更深入地了解为什么
HistoryEntry
指向 User(18) 没有收到更改通知,因为 User(18) 确实存在。 - 此外,我需要找到一个解决方案,在将
HistoryEntry
User(18) 添加到用户 HashMap 时更新指向 User(18) 的解决方案。