简体   繁体   English

为什么我的KnockoutJS自定义绑定会被触发?

[英]Why is my KnockoutJS custom binding being triggered?

I've got an odd situation. 我有一个奇怪的情况。 Basically, I have two custom bindings which are used to animate the DOM element to it's new value. 基本上,我有两个自定义绑定,用于将DOM元素设置为它的新值。 These are aWidth and aRight, which animate the width and right values respectively. 这些是aWidth和aRight,分别为宽度值和右值设置动画。

I've implemented the bindings like this: 我已经实现了这样的绑定:

<div class='classname' data-bind="aRight: right, aWidth: containerWidth, style: { zIndex: zindex, left: (left() + 'px'), height: (containerHeight() + 'px') }">

... and the custom bindings look like this: ...并且自定义绑定看起来像这样:

            ko.bindingHandlers.aWidth =
            {
                update: function (element, valueAccessor, allBindingsAccessor, context)
                {
                    // Get the value accessor
                    var value = valueAccessor();

                    // Get the new width and the duration of the animation
                    var newWidth = ko.utils.unwrapObservable(value);
                    var duration = 500;

                    $(element).animate({ width: newWidth }, duration, "swing");
                }
            };

            ko.bindingHandlers.aRight =
            {
                update: function (element, valueAccessor, allBindingsAccessor, context)
                {
                    // Get the value accessor
                    var value = valueAccessor();

                    // Get the new width and the duration of the animation
                    var newRight = ko.utils.unwrapObservable(value);
                    var duration = 500;

                    $(element).animate({ right: newRight }, duration, "swing");

                    console.log("aRight Called: newRight - " + newRight + ", duration - " + duration);
                }
            };

So the problem comes around when we change an observable other than my two custom bound observables, for instance zindex. 因此,当我们更改除两个自定义绑定observable之外的observable时,问题就出现了,例如zindex。

If we change the observable zindex, the value gets updated correctly in the DOM, but for some reason, my aRight binding also gets triggered!... 如果我们更改了可观察的zindex,那么值会在DOM中正确更新,但由于某种原因,我的aRight绑定也会被触发!...

I don't have any reference to it in my aRight custom binding so there surely can't be a dependency? 我的aRight自定义绑定中没有任何引用,所以肯定不能依赖它?

My aRight binding also gets triggered when my aWidth binding is triggered too, which is also a little odd! 当我的aWidth绑定也被触发时,我的aRight绑定也会被触发,这也有点奇怪!

Does anyone have any ideas about this? 有没有人对此有任何想法?

Thanks a lot! 非常感谢!

Andy. 安迪。

Update 更新

This is the part of the view model which updates the index, which when causes my aRight custom binding to fire (this is very much psudo-code by the way!): 这是更新索引的视图模型的一部分,当导致我的aRight自定义绑定触发时(顺便说一下这是非常多的psudo代码!):

    var page = function()
    {
        this.zindex = ko.observable(0);
        this.right = ko.observable(0);
        // and other observables....
    }

    var viewModel = function()
    {
        var pages = ko.oberservableArray();
        // populate the pages array etc...

        this.someMethod = function()
        {
            // Do some stuff...
            this.anotherMethod();
            // Do some other stuff
        }
        .bind(this);

        this.anotherMethod() = function
        {
            var pageCount = this.pages().length;
            for (var pageNum = 0; pageNum < pageCount; pageNum++)
            {
                var page = this.pages()[pageNum];
                page.zindex(/* a different value */); // This is what causes my aRight binding to fire...
            }
        }
        .bind(this);
    }

Update 更新

I just read a post here: http://groups.google.com/group/knockoutjs/browse_thread/thread/26a3157ae68c7aa5/44c96d1b748f63bb?lnk=gst&q=custom+binding+firing#44c96d1b748f63bb 我刚看了一篇帖子: http//groups.google.com/group/knockoutjs/browse_thread/thread/26a3157ae68c7aa5/44c96d1b748f63bb?lnk=gst&q=custom+binding+firing#44c96d1b748f63bb

Saying: 他说:

Additionally, a binding will have its update function run again, if another binding in the same data-bind attribute is triggered as well. 此外,如果同一数据绑定属性中的另一个绑定也被触发,则绑定将再次运行其更新功能。

Does this mean that what I am seeing is that my custom binding is being triggered when any other binding the in data-bind attribute is triggered (it just so happens maybe that zindex is the first that I see change)? 这是否意味着我所看到的是,当触发data-bind属性中的任何其他绑定时,我的自定义绑定被触发(这恰好可能是zindex是我看到的第一个更改)? Is this not a bit odd/wrong?... 这不是有点奇怪/错吗?......

Update 更新

I've got a simple fiddle which I think pretty much sums up my problem. 我有一个简单的小提琴,我认为这几乎总结了我的问题。 It seems like any binding on the same data-bind attribute as much custom binding will cause it to update! 似乎任何绑定在相同的数据绑定属性上的自定义绑定都会导致它更新!

http://jsfiddle.net/J6EPx/2/ http://jsfiddle.net/J6EPx/2/

Hmmm... guess I'll have to work around it by manually checking in my custom binding as to whether the value has actually changed or not!! 嗯...我猜我必须通过手动检查我的自定义绑定来解决它是否实际改变了值! Does this not defeat that actual point of a binding??? 这不会破坏绑定的实际点吗???

I've also posted a more precise question on the Knockout forums: http://groups.google.com/group/knockoutjs/browse_thread/thread/d2290d96e33f1d5a 我还在Knockout论坛上发布了一个更精确的问题: http//groups.google.com/group/knockoutjs/browse_thread/thread/d2290d96e33f1d5a

This is currently by design. 这是目前的设计。 All bindings in a data-bind are triggered when any of bindings fire. 触发任何绑定时,将触发数据绑定中的所有绑定。 This is because they are all wrapped in a single dependentObservable. 这是因为它们都包含在一个dependentObservable中。 In some cases, bindings have a dependency between each other (if options are updated, then value needs to run to ensure that it is still a valid value). 在某些情况下,绑定之间存在依赖关系(如果更新选项,则需要运行值以确保它仍然是有效值)。 However, in some cases, this does cause a problem. 但是,在某些情况下,这确实会导致问题。

There is a different pattern that you can use when creating a custom binding that helps to mitigate this behavior. 在创建有助于缓解此行为的自定义绑定时,可以使用不同的模式。 Instead of defining the guts of your functionality in the "update" function, you would actually create your own dependentObservable in the "init" function. 您可以在“init”函数中创建自己的dependentObservable,而不是在“update”函数中定义功能的内容。 It would look like: 它看起来像:

ko.bindingHandlers.custBinding= {
    init: function(element, valueAccessor) {
        ko.dependentObservable({
            read: function() {
                ko.utils.unwrapObservable(valueAccessor());
                alert("custBinding triggered"); 
            },
            disposeWhenNodeIsRemoved: element
        });
    }
};

http://jsfiddle.net/rniemeyer/uKUfy/ http://jsfiddle.net/rniemeyer/uKUfy/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM