Пользовательская привязка Knockout срабатывает несколько раз

В настоящее время я пытаюсь создать пользовательскую привязку для своей веб-страницы, где у меня есть видимый диапазон и скрытый элемент ввода. Если я нажму на диапазон, он исчезнет, ​​и появится ввод. Как только ввод теряет фокус, диапазон обновляется новым значением из ввода. Однако по какой-то причине моя функция blur снова привязывается каждый раз, когда я нажимаю на свой диапазон, а это не то, чего я хочу. Как я могу это исправить?

HTML

<!-- ko foreach: formula -->
  <span data-bind="text: $data, attr: {name: $index}, convert: $index()"></span>
  <input data-bind="value: $data, attr: {name: $index}" class="hide"/><br/>
<!-- /ko -->

JavaScript

ko.bindingHandlers.convert = {
  init: function(element, valueAccessor) {
    $(element).click(function() {
      var index = valueAccessor();
      var inputName = "input[name="+index+"]";
      $(element).addClass("hide");
      $(inputName).removeClass("hide").focus().blur(function() {
        console.log("firing");
        $(inputName).addClass("hide");
        $(element).removeClass("hide");
        $(element).text($(inputName).val());
      });
    });
  }
};

Итак, если я дважды нажму на свой диапазон, я получу

firing
firing
firing

в моей консоли, когда я должен получить firing только дважды.

Примечание. Я не могу следовать примеру hasFocus из учебника Knockout, поскольку он привязывается ко всем полям ввода, и мне нужно, чтобы мои поля ввода переключались только для того конкретного диапазона, по которому выполняется щелчок.


person Wei Hao    schedule 12.06.2012    source источник


Ответы (1)


Это вовсе не загадка. Посмотрите на этот код:

$(element).click(function() {
    /* some code */
    $(inputName).blur(function() {
        /* some code */
    });
});

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

$(element).click(function() {
    var $element = $(this);
    var index = valueAccessor();
    var inputName = "input[name="+index+"]";
    var $input = $(inputName);
    $element.addClass("hide");
    $input.unbind('blur');
    $inputName.removeClass("hide").focus().blur(function() {
        console.log("firing");
        $input.addClass("hide");
        $element.removeClass("hide");
        $element.text($input.val());
    });
});

Я думаю, что вы можете связать это, хотя не проверял.

person freakish    schedule 12.06.2012
comment
Я не могу поверить, что это было так просто! Спасибо! Однако мне не нужна была вторая функция развязки. $(inputName).unbind('blur'); было достаточно, чтобы код работал. - person Wei Hao; 12.06.2012
comment
@WeiHao Конечно. Я ушел вторым unbind по ошибке. Я отредактировал код. :) Кстати: я немного рефакторил ваш код, я закэшировал некоторые переменные, чтобы сделать его более эффективным. - person freakish; 12.06.2012