【问题标题】:Knockout Can I get around this computed loop?淘汰赛 我可以绕过这个计算循环吗?
【发布时间】:2013-04-20 05:28:24
【问题描述】:

我的视图模型中的一堆对象具有以下结构

我有一个底层数组,其中填充了包含 ko.observable 项的对象。

例如:选择 = [{Legs:{'0':ko.observable(12)}}, {Legs:{'0':ko.observable(0)}}]

我想要实现的是,当用户单击复选框时,应该切换该 Runner 的 Selected 值。现在,当这种情况发生时,我还想更新 Cache 值以反映 Runners 选择的状态

缓存用作二进制存储 12 == 1100 == 复选框 3 和 4 被选中

现在我可以开始工作了,我显然不需要让 Cache 可观察。

但是,我还需要以编程方式更改缓存值,并且我希望复选框自动反映这些更改。

下面的内容可以正常工作,但会创建一个循环,可以优雅地处理淘汰赛,但其结果不可靠,这会减慢速度。

如何创建此绑定设置?

function Runner(name, odds, race, leg, post) {
    var runner = {
        Name: name,
        Odds: odds,
        Post: post,
        Race: race,
        Leg: leg,
        Cache: selections[race].Legs[leg],
        Selected: ko.observable(false),
        Enabled: ko.observable(true),
        Valid: true
    };

    runner.Check = ko.computed(function() {
        if (!this.Enabled.peek() || !this.Valid ) return;
        var checked = this.Selected();
        var cache = this.Cache();

        if (checked) {
            this.Cache(cache | 1 << this.Post);
        } else {
            this.Cache(cache & ~(1 << this.Post));
        }

    }, runner);

    return runner;
}

编辑

<input type="checkbox" data-bind="checked: Selected, enable: Enabled"/>

【问题讨论】:

  • 我无法弄清楚 Check 计算应该如何与跑步者相关。您可以向我们展示您的标记或创建一个小提琴来演示吗?
  • 用户点击复选框 -> 选择匹配的更改 -> 检查自选择更改后触发 -> 在缓存中设置正确的位标志 -> (循环从这里开始)调用检查缓存更改等...哦,我猜想我可以添加一行说:检查位值,如果它与 Selected 相同,则什么也不做,这将退出循环是吗?

标签: javascript knockout.js knockout-2.0


【解决方案1】:

写完我的问题后,我有片刻的清醒。但我认为这是一个很好的问题,而不是改变或删除我的问题,我只是发布我的最新解决方案并希望得到一些批评。

所以最后我完全放弃了 Selected 值

注意 this.Post + 1 是根据我的需要而定的,通常不需要它,我只是希望保留第一个位以备将来使用。

    runner.Check = ko.computed({
        read: function() {
            var cache = ko.utils.unwrapObservable(this.Cache); //Edit 1
            return cache & 1 << (this.Post + 1);
        },
        write:function(value) {
            var cache = this.Cache();
            if (!this.Enabled.peek() || !this.Valid || this.Post === -1) return;
            var mask = 1 << (this.Post+1);
            if(value === !(cache & mask)){ //Edit 2
                this.Cache(value ? cache | mask : cache & ~mask);
            }
        }
    }, runner);

以这种方式做事的一个坏事是,如果我有 20 个跑步者都使用相同的 Cache,那么当用户选择其中 1 个时,所有 20 个都会重新检查自己...

对于我的具体情况,未来的更改可能是删除 Peek on Enabled,并执行一个检查,如果 !Enabled 然后默认关闭该位,而不是可能允许 Disabled Checked 复选框。

编辑

将“读取”函数更改为使用 unwrapObservable(),以防缓存被其他地方删除/移除的 observable 清除。

编辑 2

在回答原始问题中的评论时,我意识到为了帮助防止一些多余的调用,我可以添加一个检查以查看该位的值是否已经等于 value,如果是,则什么也不做,所以如果以编程方式我尝试打开一点已经开启,那么它不会触发计算,因为实际上没有任何改变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-29
    • 2019-10-03
    • 2012-06-12
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    相关资源
    最近更新 更多