2013-03-22 2 views
1

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

Большинство связывание был взят из примера Райан Niemeyers - найдено here

HTML

<div data-bind="clickToEdit: { data: items, buttonText: 'New Item' }"></div> 

связывание

ko.bindingHandlers.clickToEdit = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) { 
     var options = valueAccessor() || {}; 

     var editing = ko.observable(false); 
     var newValue = ko.observable(); 

     var button = $('<a class="btn btn-mini" href="#">' + options.buttonText + '</a>').prepend('<span class="icon-plus"></span>').appendTo(element)[0]; 
     var input = $('<input type="text">').appendTo(element)[0]; 

     ko.applyBindingsToNode(button, { 
      hidden: editing, 
      click: function() { 
       editing(true); 
      } 
     }); 

     ko.applyBindingsToNode(input, { 
      value: newValue, 
      visible: editing, 
      hasFocus: editing, 
      //valueUpdate: 'afterkeydown', 
      onEnter: function(data) { 
       debugger; 
       options.data.push(data); 
       editing(false); 
      } 
     }); 
    } 
}; 

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

Пожалуйста, смотрите мои fiddle для законченного примера

ответ

1

Две вещи, которые могут помочь:

  • applyBindingsToNode вызов принимает третий аргумент, где вы можете предоставить контекст. В некоторых моих примерах контекст был неактуальным, поскольку он писал непосредственно наблюдаемому и не нуждался в данных. Итак, вы можете передать context (или viewModel) в качестве третьего аргумента на ваш второй звонок applyBindingsToNode.

  • Если я понимаю, что вы пытаетесь сделать, то я бы подумал, что вы можете просто сделать что-то вроде: options.data.push(new Item(newValue()); и не нужно беспокоиться о контексте/данных (что было бы общей моделью просмотра, так как вы находятся в области верхнего уровня).

Пример: http://jsfiddle.net/rniemeyer/Pmns4/

+0

Совершенная, ваша вторая пуля квадрат. Спасибо – bflemi3

+0

Выполнение 'new Item (newValue())' привязка теперь tighlty связана с моделью. Разве это не плохая практика? Будет ли более предпочтительный способ, чтобы привязка ничего не знала о модели? – bflemi3

+0

Я могу придумать очевидный способ, передав в качестве опции новый элемент для добавления, возможно, что-то вроде этого ... 'data-bind =" clickToEdit: {data: items, newItem: new Item ({}), buttonText : 'New Item'} '. Это кажется грязным, хотя – bflemi3

 Смежные вопросы

  • Нет связанных вопросов^_^