Knockout.js “带”绑定更新之前的动画

Knockout.js “带”绑定更新之前的动画,knockout.js,Knockout.js,我使用的是绑定,我想在更改值之前和之后调用一些动画。有人知道怎么做吗?您可以使用自己的绑定来包装绑定,该绑定使用jQuery来制作一些动画,例如: ko.bindingHandlers['fadingWith'] = { init: function(element, valueAccessor, allBindingsAccessor, context) { return ko.bindingHandlers['with']['init'](element, value

我使用的是绑定,我想在更改值之前和之后调用一些动画。有人知道怎么做吗?

您可以使用自己的绑定来包装绑定,该绑定使用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;
然后您可以这样应用它:

我还没有测试过这个,我稍后会尝试,但我认为这将是一个方向

我更确信的另一个选项是,您可以创建一个单独的绑定,该绑定执行以下操作:

ko.bindingHandlers['fadeOn'] = {
    update: function(element) {
        $(element).hide().fadeIn(200);
    }
}
这不会在可观察到的更改之前为您提供动画,但会在更改之后为您提供动画。你会这么做吗

编辑:我刚才提出的另一个可能更简单的选项是对正在使用的变量使用throttle扩展:

视图模型:

///...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);
    }
}
请注意,淡出时间与油门时间相同

然后你就这样把它绑起来:


将发生的情况是,当您更改ObservalethatNeedswith时,fadeInOut处理程序将开始转换元素。然后,在它完成的时刻,在这种情况下,当fadeInOut开始淡入元素时,油门将赶上,delayedObservable将立即更新。它会在一件事情中淡出,在另一件事情中淡出。

您可以使用自己的绑定来包装绑定,该绑定使用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;
然后您可以这样应用它:

我还没有测试过这个,我稍后会尝试,但我认为这将是一个方向

我更确信的另一个选项是,您可以创建一个单独的绑定,该绑定执行以下操作:

ko.bindingHandlers['fadeOn'] = {
    update: function(element) {
        $(element).hide().fadeIn(200);
    }
}
这不会在可观察到的更改之前为您提供动画,但会在更改之后为您提供动画。你会这么做吗

编辑:我刚才提出的另一个可能更简单的选项是对正在使用的变量使用throttle扩展:

视图模型:

///...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);
    }
}
请注意,淡出时间与油门时间相同

然后你就这样把它绑起来:


将发生的情况是,当您更改ObservalethatNeedswith时,fadeInOut处理程序将开始转换元素。然后,在它完成的时刻,在这种情况下,当fadeInOut开始淡入元素时,油门将赶上,delayedObservable将立即更新。它在一件事上消失,在另一件事上消失。

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

之前设置此绑定非常重要。我通过创建创建元素副本的绑定解决了此问题。克隆此元素后,我将对其设置动画,然后删除它并使用新值对原始元素设置动画。在使用Los Frijoles之前设置此绑定非常重要。第三种解决方案将不起作用,因为它将限制“使用”绑定始终在动画之后进行

由于我们正在尝试通过绑定为渲染的元素设置动画,因此当从未渲染状态转到渲染状态时,动画将尝试为不存在的元素设置动画

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

编辑: 我已经意识到,可以通过将“with”或“if”绑定替换为具有等效逻辑的“template”或“foreach”标记来为其设置动画。例如,我替换了:

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

我的示例中的“SelectedTimeFase”没有必要成为一个列表。使用此功能,我现在可以在设置SelectedTimeRelease时转换进入和退出模式对话框。这种技术也可以用于if转换:

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

My utils.kbAnimFadeIn/Out函数与此处的击倒动画示例页面中演示的函数等效:

Los Frijoles第三个解决方案不起作用,因为它将限制“with”绑定始终在动画之后发生

由于我们正在尝试通过绑定为渲染的元素设置动画,因此当从未渲染状态转到渲染状态时,动画将尝试为不存在的元素设置动画

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

编辑: 我已经意识到,可以通过将“with”或“if”绑定替换为具有等效逻辑的“template”或“foreach”标记来为其设置动画。例如,我替换了:

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

没有必要 将我示例中的“SelectedTimeFase”作为列表。使用此功能,我现在可以在设置SelectedTimeRelease时转换进入和退出模式对话框。这种技术也可以用于if转换:

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

My utils.kbAnimFadeIn/Out函数与此处的击倒动画示例页面中演示的函数等效:

我以前尝试过第一个解决方案,但似乎没有调用in'with'绑定更新函数。我对第三个解决方案的实际效果比第一个更有信心,因为我看不到任何方法可以释放页面进行渲染,同时在第一个解决方案中保持更新函数处于活动状态,以便它可以返回with update函数的值,这就是问题所在正在发生…with update返回值正在丢失,它实际上很重要,因为它控制了已死亡的元素。我以前尝试过第一个解决方案,但似乎没有调用in'with'绑定更新函数。我对第三个解决方案的实际效果比第一个更有信心,因为我看不到任何方法可以释放页面进行渲染,同时在第一个解决方案中保持更新函数处于活动状态,以便它可以返回with update函数的值,这就是问题所在正在发生…with update返回值正在丢失,它实际上很重要,因为它控制了已死亡的元素。