2013-06-06 5 views
1

Давайте возьмем пример из корзины ...Нокаут - повторное использование такой же вид модели

Каждый раз, когда пользователь выбирает элемент, мы переместить его в линию нашей корзине.

/* would normally autoincrement */ 
var num = '1'; 
document.getElementById('cart').innerHTML = oldHTML + 
"<div id='line" + num + "'> 
<input type='text' data-bind='value: quantity'> 
<input type='text' data-bind='value: price'> 
<input type='text' data-bind='value: extendedPrice'> 
</div>";` 

var lineVM() { 
    var self = this; 
    self.quantity = ko.observable(); 
    self.price = ko.observable(); 
    self.extendedPrice = ko.computed(function() {return self.price() * self.quantity();}); 
} 

ko.applyBindings(new lineVM(), document.getElementById('line' + num)); 

Как строки добавляются, мы имеем line1, line2 и т.д ...

Из документов:

При желании, вы можете передать второй параметр, чтобы определить, какая часть документ, который вы хотите найти для атрибутов привязки данных. Например, ko.applyBindings (myViewModel, document.getElementById ('someElementId')). Это ограничивает активацию элемента с идентификатором someElementId и его потомками, что полезно, если вы хотите иметь несколько моделей просмотра и связывать их с другой областью страницы.

Тестирование показывает, что нет разделения ... Если я повторно использую модель представления, добавив еще одну строку «пробелы» в одну перед ней. Однако мне нужна одна и та же модель представления для неопределенного количества строк. Я не хочу создавать 100 моделей взглядов для каждой потенциальной линии, и я не хочу, чтобы моя корзина ломалась для клиента, у которого будет 101 элемент.

Итак, что, если у меня есть одна модель представления и вы хотите связать ее с несколькими регионами на странице? Документы на самом деле не говорят. Я делаю это неправильно, я пытаюсь сделать что-то нокаутом, которого не допускают?

Большое спасибо за помощь.

ответ

1

Я думаю, вы должны переосмыслить свой дизайн в целом. Почему бы не сделать что-то подобное?

var viewModel = function() { 
    var self = this; 
    self.items = ko.observableArray(); 
    self.addItem = function(num, quantity, price) { 
     var item = { 
      num: num, 
      quantity: ko.observable(quantity), 
      price: ko.observable(price) 
     }; 
     item.extendedPrice = ko.computed(function() { 
      return item.price() * item.quantity(); 
     }, self); 
     self.items.push(item); 
    }; 
}; 

ko.applyBindings(new viewModel()); 

Html:

<div data-bind="foreach: items"> 
    <div data-bind="attr: { id: 'line' + num }"> 
     <input type="text" data-bind="value: quantity" /> 
     <input type="text" data-bind="value: price" /> 
     <input type="text" data-bind="value: extendedPrice" readonly="readonly" /> 
    </div> 
</div> 

Принцип заключается в том, чтобы добавить элементы в observableArray, чтобы изменить вид. Вы действительно не должны динамически создавать модели просмотра.

С помощью этого кода вы должны иметь способ позвонить self.addItem, и это зависит от остальной части вашего кода.

Edit:, кстати, линия var lineVM() { в вашем коде должен быть var lineVM = function() {

Кроме того, извините, если кто-то из этого кода не работает, это проверялось, но должно помочь вам получить идею.

+0

Если использование нокаута требует от меня полной редизайна моей страницы, то я могу просто использовать стандартные обработчики javascript. Я использовал простой пример, потому что никто не хочет читать 300 строк кода ... «Реальное» приложение использует карты Google, с его слушателями. Преобразование 300 строк кода просто для того, чтобы сделать эту работу слишком много. Не говоря уже о том, что я не собираюсь переходить к следующему «Как это сделать» при попытке подключить два отдельных набора обработчиков событий. Однако я очень благодарен за ответ, и я уверен, что он будет полезен для более сложной карты данных в менее сложной среде. –

+0

Да, при использовании нокаута обычно требуется полная редизайн, если вы используете его правильно. Он предназначен для разделения представления из режима просмотра. С нокаутом вы не должны обновлять представление (html) с помощью javascript вообще. Это нарушает шаблон MVVM, который использует нокаут.Вы должны обновлять наблюдаемые и наблюдаемые массивы с помощью javascript (с этими объектами, на которые ссылаются в представлении). В конечном счете, это делает вещи A LOT более простыми, и я настоятельно рекомендую следовать шаблону MVVM. Удачи вам с вашим приложением! –

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