javascript - 如何强制 knockoutjs 更新 UI(重新评估绑定(bind))

标签 javascript knockout.js

(我知道这里还有其他问题问同样的事情;我试过了,但它们在这里不适用)

我有一个由 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() 的地方使用它,它会在需要时自动重绘。

http://jsfiddle.net/2us8m/3/

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 时,它能够“优化”并防止重绘整个内容。但要小心,因为如果它不能猜测你没有改变很多东西,它可能会重新绘制整个可观察树(这在性能方面可能会非常糟糕)

在您的示例中,我们可以使用与我修改后的示例相同的行为:

http://jsfiddle.net/2us8m/4/

关于javascript - 如何强制 knockoutjs 更新 UI(重新评估绑定(bind)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20670989/

相关文章:

knockout.js - 我们可以在一个页面中调用多个 ko.applyBindings 方法吗?

javascript - Page.ResolveUrl 在 JavaScript 中不起作用

javascript - 从元素属性值初始化 Knockout observable

javascript - 使用 knockout.js Ping 网站

c# - 对 ASP post 方法的 Ajax 调用不断给出 null 参数

模糊事件的Javascript测试

javascript - 复选框未检查到正确的值

javascript - Node-express应用程序中的抛出错误

javascript - meteor 中的每个模板循环多次

javascript - 单击后退按钮时重定向到不同页面 "not working"