(我知道这里还有其他问题问同样的事情;我试过了,但它们在这里不适用)
我有一个由 Knockout JS foreach
显示的集合。对于每个项目,visible
绑定(bind)是通过调用一个基于项目本身外部的方法的方法来设置的。当外部性发生变化时,我需要重新绘制 UI。
可以在这个 Fiddle 中看到精简版:http://jsfiddle.net/JamesCurran/2us8m/2/
它以四个文件夹名称的列表开头,并显示以“S”开头的文件夹。
<ul data-bind="foreach: folders">
<li data-bind="text: $data,
visible:$root.ShowFolder($data)"></li>
</ul>
<button data-bind="click:ToA">A Folders</button>
点击按钮应该显示以“A”开头的按钮。
self.folders = ko.observableArray(['Active', 'Archive', 'Sent', 'Spam']);
self.letter = 'S';
// Behaviours
self.ShowFolder = function (folder)
{
return folder[0] === self.letter;
}
self.ToA = function ()
{
self.letter = 'A';
}
更新:
在 Loic 向我展示修复此示例有多么容易之后,我回顾了此示例与我的实际代码之间的差异。我使用一个空对象作为字典来切换是否选择了一个项目 self.Selected()[item.Id] = !self.Selected()[item.Id];
被改变的对象已经是一个可观察对象。我假设 Knockout 没有意识到该列表依赖于外部可观察对象,但它确实如此。 Knockout 所缺少的是可观察对象实际上正在发生变化。因此,解决方案很简单:
self.Selected()[item.Id] = !self.Selected()[item.Id];
self.Selected.notifySubscribers();
最佳答案
这是我想出的:
您必须了解的是,Knockout 只是“回答”可观察对象中的数据变化。如果一个 observable 发生变化,它会触发每个使用它的对象。通过使您的 self.letter
成为可观察对象。您可以简单地更改它的值并在类似 self.letter()
的地方使用它,它会在需要时自动重绘。
function WebmailViewModel() {
// Data
var self = this;
self.folders = ko.observableArray(['Active', 'Archive', 'Sent', 'Spam']);
self.letter = ko.observable('S');
// Behaviours
self.ShowFolder = function (folder)
{
return folder[0] === self.letter();
}
self.ToA = function ()
{
self.letter('A');
}
};
ko.applyBindings(new WebmailViewModel());
如果您有复杂的绑定(bind),例如将对象存储在可观察对象中。如果您想修改该对象,您有多种可能的选择。
self.Selected()[item.Id] = !self.Selected()[item.Id];
您可以通过使所有内容都“可观察”来将其更改为此,但如果我没记错的话,它可能会变得复杂。
self.Selected()[item.Id](!self.Selected()[item.Id]());
我记得我有一个类似的问题,我有依赖性问题,我必须更新一个国家、地区、城市。我最终将它存储为可观察对象中的列表,以防止对单个元素更改进行更新。我有这样的事情。
var path = PathToCity();
path[0] = 'all';
path[1] = 'all';
PathtoCity(path);
通过这样做,更改将是原子的,并且只会有一个更新。我已经有一段时间没有玩 knockout 了。我不确定,但我相信上次我使用 knockout 时,它能够“优化”并防止重绘整个内容。但要小心,因为如果它不能猜测你没有改变很多东西,它可能会重新绘制整个可观察树(这在性能方面可能会非常糟糕)
在您的示例中,我们可以使用与我修改后的示例相同的行为:
关于javascript - 如何强制 knockoutjs 更新 UI(重新评估绑定(bind)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20670989/