'with'绑定更新前的动画

时间:2012-07-19 09:59:55

标签: knockout.js

我正在使用“with”绑定,我想在更改值之前调用一些动画,之后。有没有人知道怎么做?

3 个答案:

答案 0 :(得分:3)

您总是可以使用自己的绑定来包装with绑定,该绑定使用jQuery来执行某些动画:

ko.bindingHandlers['fadingWith'] = {
    init: function(element, valueAccessor, allBindingsAccessor, context) {
        return ko.bindingHandlers['with']['init'](element, valueAccessor, allBindingsAccessor, context);
    },
    update: function(element, valueAccessor, allBindingsAccessor, context) {
        $(element).fadeOut(100, function () {
            ko.bindingHandlers['with']['update'](element, valueAccessor, allBindingsAccessor, context)
        }).fadeIn(100);
    }
};
ko.virtualElements.allowedBindings['fadingWith'] = true;

然后你可以这样申请:<div data-bind="fadingWith: someObservable"><span data-bind="text: $data"></span></div>

我没有测试过这个(我稍后会试一试),但我认为这是方向。

另一个选项(我更确定会有效)是你创建了一个单独的绑定来执行以下操作:

ko.bindingHandlers['fadeOn'] = {
    update: function(element) {
        $(element).hide().fadeIn(200);
    }
}

在可观察到的更改之前,它不会为您提供动画,但它会在之后为您提供动画。所以你会做<div data-bind="with: someObservable, fadeOn: someObservable"><span data-bind="text: $data"></span></div>

编辑:我刚才想出的另一个 可能更容易的 选项是对您使用with的变量使用限制扩展:

视图模型:

///...your code....
this.observableThatNeedsWith = ko.observable("Hello");
this.delayedObservable = ko.computed(this.observableThatNeedsWith).extend({throttle: 200});
//...continue your code

然后,你有一个绑定如下:

ko.bindingHandlers['fadeInOut'] = {
    update: function(element) {
        $(element).stop(true, true).stop(true, true).fadeOut(200).fadeIn(200);
    }
}

请注意,淡出时间与节流时间相同。

然后你这样绑定它:<div data-bind="with: delayedObservable, fadeInOut: observableThatNeedsWith"><span data-bind="text: $data"></span></div>

当您更改observableThatNeedsWith时,fadeInOut处理程序将开始转换元素。然后,当它完成淡出(在这种情况下为200ms)时,油门将赶上并且delayedObservable将在fadeInOut开始逐渐淡化元素时更新。它淡出一件事,然后淡入另一件事。

答案 1 :(得分:1)

我通过创建创建元素副本的绑定来解决问题。在克隆这个元素后,我为它设置动画,之后我将其删除并使用新值设置原始元素。在

之前设置此绑定非常重要

答案 2 :(得分:0)

Los Frijoles第3个解决方案无效,因为它会限制'with'绑定总是在动画之后发生。

由于我们试图为with绑定所呈现的元素设置动画,因此当从未渲染状态转换为渲染状态时,动画将尝试为不存在的元素设置动画。

Slawomir的回答是我见过的最好的,但是在移动设备上制作动画时克隆复杂元素不是出于性能原因的选择。正确实现这些绑定的动画需要改进Knockout框架。

编辑: 我已经意识到,通过用等效逻辑的“模板”或“foreach”标签替换它,可以为'with'或'if'绑定设置动画。例如,我替换了:

<div data-bind="with: selectedTimelapse">

使用:

<div data-bind="template: {
    foreach: selectedTimelapse,
    afterAdd: utils.kbAnimFadeIn,
    beforeRemove: utils.kbAnimFadeOut
}">

我的示例中不需要'selectedTimelapse'作为列表。使用此功能,我可以在设置selectedTimelapse时进入和退出我的模态对话框。这种技术可以被黑客攻击,以便在过渡时使用:

<div data-bind="template: {
    foreach: (showTimelapse()) ? selectedTimelapse : undefined,
    afterAdd: utils.kbAnimFadeIn,
    beforeRemove: utils.kbAnimFadeOut
}">

我的utils.kbAnimFadeIn / Out函数等同于Knockout动画示例页面中演示的函数:http://knockoutjs.com/examples/animatedTransitions.html