Почему срабатывает моя пользовательская привязка KnockoutJS? - PullRequest
6 голосов
/ 30 ноября 2011

У меня странная ситуация. По сути, у меня есть две пользовательские привязки, которые используются для анимации элемента DOM к его новому значению. Это aWidth и aRight, которые анимируют ширину и правильные значения соответственно.

Я реализовал привязки так:

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

... и пользовательские привязки выглядят так:

            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);
                }
            };

Таким образом, проблема возникает, когда мы меняем наблюдаемую информацию, отличную от двух моих пользовательских привязанных наблюдаемых, например, zindex.

Если мы изменим наблюдаемый zindex, значение будет корректно обновлено в DOM, но по какой-то причине моя привязка aRight также сработает! ...

У меня нет ссылки на него в моей пользовательской привязке aRight, поэтому, конечно, не может быть зависимости?

Моя привязка aRight также запускается, когда также активируется моя привязка aWidth, что тоже немного странно!

У кого-нибудь есть идеи по этому поводу?

Большое спасибо!

Энди.

Update

Это часть модели представления, которая обновляет индекс, что вызывает срабатывание моей пользовательской привязки aRight (кстати, это очень псевдокод!):

    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);
    }

Обновление

Я только что прочитал пост здесь: http://groups.google.com/group/knockoutjs/browse_thread/thread/26a3157ae68c7aa5/44c96d1b748f63bb?lnk=gst&q=custom+binding+firing#44c96d1b748f63bb

Высказывание:

Кроме того, для привязки будет снова запущена функция обновления, если также запускается другая привязка в том же атрибуте привязки данных.

Означает ли это, что я вижу, что моя пользовательская привязка срабатывает, когда запускается любая другая привязка атрибута in-bind (просто так может быть, что zindex - первое, что я вижу изменения)? Разве это не немного странно / неправильно? ...

Обновление

У меня есть простая скрипка, которая, я думаю, в значительной степени подводит итог моей проблемы. Кажется, что любая привязка к одному и тому же атрибуту привязки данных, так как много пользовательских привязок приведут к его обновлению!

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

Хммм ... думаю, мне придется обойти это, вручную проверив мою пользовательскую привязку относительно того, действительно ли значение изменилось или нет !! Разве это не разрушает эту фактическую точку привязки ???

Я также разместил более точный вопрос на форумах Knockout: http://groups.google.com/group/knockoutjs/browse_thread/thread/d2290d96e33f1d5a

1 Ответ

9 голосов
/ 30 ноября 2011

Это в настоящее время дизайн.Все привязки в привязке данных запускаются при срабатывании любой из привязок.Это потому, что все они обернуты в один зависимый объект.В некоторых случаях привязки имеют зависимость друг от друга (если параметры обновляются, необходимо запустить значение, чтобы убедиться, что оно все еще является допустимым значением).Однако в некоторых случаях это вызывает проблему.

Существует другой шаблон, который можно использовать при создании настраиваемой привязки, которая помогает смягчить это поведение.Вместо того, чтобы определять внутренности вашей функциональности в функции «update», вы фактически создадите свой собственный зависимый объект, наблюдаемый в функции «init».Это будет выглядеть так:

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/

...