将 jQuery.animate() 添加到 Knockout.js 自定义绑定中

Adding jQuery.animate() to a Knockout.js custom binding?

本文关键字:js Knockout 自定义 绑定 添加 jQuery animate      更新时间:2023-09-26

我正在使用 SignalR 和 Knockout.js 在服务器上的模型发生变化时在我的视图中显示移动。

我的实体有一个非常简单的 ViewModel(它们是红色的小方块,当它们"移动"服务器端时,它们会在屏幕上"移动"):

function Entity(data) {
    var self = this;
    self.id = data.UID;
    self.left = ko.observable(data.Left);
    self.top = ko.observable(data.Top);
}

我的 HTML 的 Knockout 模板如下(值得注意的是,我的 CSS 类实体分配了绝对定位):

<!-- ko foreach: entities -->
    <div data-bind="attr: { id: 'ent' + id }, style: { top: (top() + 'px'), left: (left() + 'px')}" class="entity">
    </div>
<!-- /ko -->

因此,当服务器上的模型发生更改时(在本例中为"位置"属性),我使用 SignalR 的 RPC 功能为每个单独的实体更新相关的 ViewModel。 这在我的 CSS left 上按预期工作,top根据 ViewModel 中的更改自动更新,但我希望它看起来漂亮而流畅。

在线搜索和 SO 以查找使用 Knockout 绑定到 ViewModel 的 jQuery 动画只会真正显示淡入/淡出可见性动画,而我本质上想在画布上显示"运动"。 有人在做类似的事情上取得了任何成功吗?

无需

通过内置的挖空绑定直接设置顶部和左侧位置,而是可以创建自己的自定义绑定。

您的 html 如下所示:

<!-- ko foreach: entities -->
  <div data-bind="attr: {id: 'ent' + id }, moveable: { top: top(), left: left()">
  </div>
<!-- /ko -->

然后,对于自定义绑定(在上面的示例中名为 moveable),您可以编写将 jQuery 过渡添加到绑定的更新函数中。它看起来大致是这样的:

update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    var values = valueAccessor();
    $(element).animate({top: values.top() + 'px', left: values.left() + 'px'}, 1);
}

稍后,您可以向自定义绑定添加更多花哨的选项和逻辑以满足您的需求。有关自定义绑定的详细信息,请参阅:http://knockoutjs.com/documentation/custom-bindings.html。

您可以将实体更改为

function Entity(data) {
    var self = this;
    self.id = data.UID;
    self.position = ko.observable({left: data.Left, top : data.Top});
}  

并使用此自定义绑定

ko.bindingHandlers.animate = {
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
       $(element).animate(valueAccessor(), 1000);
   }
};    

视图

<div data-bind="attr: { id: 'ent' + id }, animate: position()" class="entity">
</div>

JSFiddle DEMO

上面的解决方案是正确的,但它们太复杂了。

我为您的任务编写了更简单的示例 - 它更改了给定元素的"不透明度"css 属性。你可以在这里查看:http://jsfiddle.net/HjYr4/11/

ko.bindingHandlers.animateOpacity = {
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    $(element).stop(true, false);
    $(element).animate({ opacity: valueAccessor() } , 1000);
}

此外,您可能会发现阅读有关自定义绑定的文档很有用 此处 http://knockoutjs.com/documentation/custom-bindings.html (在我的示例中,animateOpactiy 是一个自定义绑定)。

祝你好运!