javascript - 借助 Knockout.js 订阅对一组对象进行动画处理?

标签 javascript jquery knockout.js observable

我花了过去 6 个小时试图解决这个问题,但我找到的关于 Knockout.js 中的订阅如何工作的文档非常少,以至于它现在已经从“有点烦人”类别转移到“彻头彻尾令人沮丧”类别。

我想要实现什么目标?

我需要对 DOM 的一部分进行动画处理,以便它根据需要上下滑动。以下是以这种方式获得动画的 DOM 的一般结构:

<section id="add" class="manageOption">
</section>
<section id="replace" class="manageOption">
</section>
<section id="remove" class="manageOption">
</section>

每个.manageOption具有相同的大小和尺寸,并且看起来非常相似。我的 ViewModel 中有一个名为 self.managementState 的可观察对象,最初设置为 false 。不相关元素上的单击绑定(bind)会将此可观察值设置为 false(如果没有显示)或添加/替换/删除(具体取决于应显示哪个元素)。只有一个.manageOption可以一次显示。

但是,只有在 self.managementState 时才会出现 SlideUp 或 SlideDown 效果。要么来自falsefalse 。因此,我不仅需要知道self.managementState的当前值还有前一篇。如果值从 add 更改至remove ,我不需要为元素设置动画,变化会立即发生。

我尝试过的

为了解决这个问题,我一直想构建一个名为 slideSwitcher 的自定义绑定(bind)。使用我所描述的上述逻辑进行操作,并且我还发现这部分代码据说会获取可观察值的先前值:

function subscribeToPreviousValue(observable, fn) {
    observable.subscribe(fn, this, 'beforeChange');
}

但我无法让它在我的 update 中很好地发挥作用我的自定义绑定(bind)中的函数,它总是返回错误的结果(例如 false 已更改为 false)。

ko.bindingHandlers.slideSwitcher = {
    update: function (element, valueAccessor) {
        var observable = valueAccessor();
        var currentVal = ko.utils.unwrapObservable(valueAccessor());

        subscribeToPreviousValue(observable, function (previous) {
            console.log('value changed from', previous, 'to', currentVal);
        });
    }
}

从根本上来说,这是因为我根本不理解“订阅”的概念,而且我自己编写绑定(bind)的经验很少。如何使用上面的订阅函数来跟踪可观察值的先前值,以及应该如何构建我的绑定(bind)来实现我所需要的?

最佳答案

第一个问题是您在更新回调中设置订阅。当某些依赖项发生更改时,将调用更新函数。所以现在订阅 beforechange 事件已经太晚了。并且您还可以在每次值更改后设置新的订阅。您必须订阅 init 函数中的值。

我喜欢 subscribeChanged 函数( Get previous value of an observable in subscribe of same observable - 第二个答案),它很好而且清晰......

ko.subscribable.fn.subscribeChanged = function (callback) {
    var oldValue;
    this.subscribe(function (_oldValue) {
        oldValue = _oldValue;
    }, this, 'beforeChange');

    this.subscribe(function (newValue) {
        callback(newValue, oldValue);
    });
};

你可以按如下方式编写绑定(bind)

ko.bindingHandlers.slideSwitcher = {
    init: function (element, valueAccessor) {
        var observable = valueAccessor();
        observable.subscribeChanged(function (newValue, oldValue) {
            console.log('value changed from', oldValue, 'to', newValue);
        });          
    }
}

关于javascript - 借助 Knockout.js 订阅对一组对象进行动画处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27847772/

相关文章:

javascript - 在 .remove() 和 .append() 之后返回按钮上的事件

javascript - 从函数和事件处理程序访问相同的变量

javascript - 与引导轮播相关的问题

javascript - 如何使用 Jquery 进行计算并将其输出为 html?

javascript - JQuery Ajax动态表单,如何在表单上方的div中显示成功消息

javascript - 如何将过滤器和网格应用于 D3 Choropleth

javascript - 使用 javascript 获取完整图像路径并放入 img src

javascript - 无法对 knockout 选项文本进行 HTML 解码

twitter-bootstrap - Bootstrap 多选的 knockout 数据绑定(bind)不选择初始数据

javascript - KnockoutJS - 在表单中使用表中的数据