Я предпочитаю, чтобы инициализировать и связать мой ViewModel сразу же, но согласен с другим плакатом, что вам нужен наблюдаемым.
Вот решение, которое продолжает создавать и связывать вашу модель просмотра сразу, как в вашем исходном примере, но вместо массива необработанных записей, которые вы получаете обратно, они преобразуют их в свои небольшие объекты модели, которые имеют наблюдаемый для счетчика и функцию приращения, которая также может быть связана с данными. Это отменит загрузку ваших данных из жизни viewmodel, поэтому, если вы хотите добавить кнопку для загрузки свежих данных, чтобы переписать ее или что-то в этом роде, это просто еще один вызов getData().
<!-- ... -->
<tbody data-bind="foreach: records">
<tr>
<td data-bind="text: counter"></td>
<td> <input type="button" value="increment" data-bind="click: increment" ></td>
</tr>
</tbody>
<!-- ... -->
<script>
function AppViewModel() {
var self = this;
self.records = ko.observableArray([]);
self.getData = function(){ /* ... */ };
self.getFakeData = function(){
var data = [{ counter: 1 }, { counter: 2}, { counter: 3 }];
var freshData = data.map(function(record){
return new AppRecord(record);
});
self.records(freshData);
};
}
function AppRecord(rawRecord) {
var self = this;
self.counter = ko.observable(rawRecord.counter);
self.increment = function(){
self.counter(self.counter() + 1);
};
}
var vm = new AppViewModel();
vm.getFakeData(); // replace with getData()
ko.applyBindings(vm);
</script>
Fiddle с getFakeData с данными выборки: https://jsfiddle.net/4hxyarLa/1/
Если вы собираетесь иметь много строк и обеспокоены примыкают памяти, можно поставить функцию приращения в способе-прототипе для AppRecord и доступ к записи через параметр функции, или вы можете добавить эту функцию в AppViewModel и привязать к $ parent.increment, чтобы вызвать ее и получить доступ к записи через параметр, переданный этой функции, чтобы увеличить его свойство счетчика.
Я не знаю, почему, но он не работает при использовании данных с сервера - он вообще не загружает их в таблицу. Я думал, что перемещение ko.applyBindings (vm); ater last parenthasis помог бы и действительно изменил что-то - теперь данные загружены, но я не получаю числа в клетках-счетчиках, но эта странная формула: function c() {if (0
suue
Нет, перемещение 'ko.applyBindings (vm);' это плохая идея, она должна оставаться в обратном вызове ajax. Лучше покажите, что вы получаете от сервера в переменной data. Можете ли вы поместить 'console.dir (data)' before' data.forEach (function (item) {'и увидеть в консоли Chrome, что у вас есть? –
Мой код был упрощен для целей вопроса, у меня есть несколько столбцов в таблице с разными именами, но я использую freeSeats в качестве счетчика здесь (я скопировал первый объект): 0: Object date: "2016-01-09 " декремент:() freeSeats: с() К: Объект Nb: 1 аргументы: NULL звонящего: нулевая длина: 0 имя: "C" прототип: с Symbol (_latestValue):" 3 " __proto__: Объект <функционал> от:" Мадрид " цена:" 30 " до:" Барселона " usernam e: "a" __proto__: Объект Я не знаю, является ли это доступным для чтения, я могу разместить содержимое данных, если вы хотите. В любом случае, данные кажутся прекрасными и загружаются, прежде чем я добавлю этот скрипт. – suue