2013-12-16 3 views
1

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

  • математике в HTML: data-bind="text: parseFloat((total * quantity), 10)"
  • с использованием ko.computed() (который «работает», но возвращает то же значение для каждой строки в целом)
  • подписавшись на событие
  • пробегает по пункту каждого observableArray с ko.utils.arrayForEach и JQuery $.each()
  • добавив ko.computed свойства с create() функции в рамках опции отображения, но я не очень понимаю, что один.

Here's a fiddle. Если у кого-то есть какие-то предложения относительно того, как я могу выполнить эту, казалось бы, простую задачу, я был бы ей признателен.

Большинство неудачных попыток находятся в комментариях к этой скрипке. Самое близкое, что я пришел, это ko.computed, но я могу получить его только для того, чтобы вернуть одно значение - значение для последней строки в таблице. Спасибо

ответ

1

Зависит то, что вы хотите достичь. Для простой цели отображения функция будет делать:

viewModel.calcTotal = function (row) { 
    return parseFloat((row.total() * row.quantity()), 10); 
}; 

Существует специальная переменная в for цикле $data, который будет проходить данные строки:

<td><span data-bind="text: $root.calcTotal($data)"></span></td> 

Кроме того, ваш первый пункт с математикой в ​​HTML будет работать, если вы добавляете круглые скобки. Простая форма привязки наблюдаемых не будет работать в выражениях.

data-bind="text: parseFloat((total() * quantity()), 10)" 
+0

Приятная и простая, именно то, что я искал. Спасибо за вашу помощь! –

1

Я внедрил рабочую версию, я не слишком хорошо разбираюсь в нокауте, хотя я не уверен, что это «правильно».

См. Следующую скрипту http://jsfiddle.net/YeSZ8/7/.

Я создал модель для каждой строки под названием ItemModel.

Он определяется как этот

var ItemModel = function (arg) { 
    var that = this; 

    this.supplier  = arg.supplier; 
    this.itemNumber = arg.itemNumber; 
    this.description = arg.description; 
    this.quantity  = ko.observable(parseInt(arg.quantity, 10)); 
    this.price  = arg.price; 
    this.total  = ko.computed(function() { 
     return that.price * that.quantity(); 
    }); 
}; 

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

EDIT: Я прочитал некоторые о плагине отображения, и я пришел к выводу, что его следует использовать с методом create, чтобы инициировать экземпляры ItemModel.

EDIT2: Исправлена ​​сломанная фильтрация, http://jsfiddle.net/YeSZ8/8/

+1

Thanks Hugo. Любая идея, как реализовать это с помощью плагина сопоставления? –

+0

@MarkB Я сам не использовал плагин сопоставления, но я предполагаю, что вы должны создать резерв 'create' для каждого элемента массива и инициировать экземпляр' ItemModel'. –

+0

Еще раз спасибо, но вот тут я застрял в своей последней точке. –

1

здесь является решением, использующее отображение плагина:

.... 
var mappingOptions = { 
    'cartItemsList': { 
     create: function (options) { 
      var result = ko.mapping.fromJS(options.data, {}); 
      result.total = ko.computed(function() { 
       return result.quantity() * parseFloat(result.price()); 
      }); 
      return result; 
     } 
    } 
}; 

var model = {cartItemsList: JSON.parse(jsonData)}; 
var viewModel = ko.mapping.fromJS(model, mappingOptions); 
viewModel.filter = ko.observable(""); 
... 

адаптированной скрипка: http://jsfiddle.net/YeSZ8/10/

+0

Фильтрация не работает над этим. Я уверен, что смогу заставить его работать с несколькими изменениями, но выбранный ответ на этот пост - очень простой вариант. Спасибо за вашу помощь. –

+0

Работа над этим: http://jsfiddle.net/YeSZ8/11/ – gbs

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