2013-04-02 1 views
0

У меня есть одиночная страница CRUD с использованием Knockout, все работает нормально, я получаю данные из вызова JSON, заполняя массив с контролируемым наблюдением со списком объектов. Я могу добавлять или редактировать отдельные элементы в этом массиве.Ноутаут автомата с форматированным столбцом (вычисленный?)

Проблема связана с форматированием валютного (числового) столбца, который я показываю в таблице со списком объектов. Я попытался использовать js-функции во многих отношениях, но форматированный объем валюты таблицы не обновляется при обновлении элемента. Если я использую привязку для форматирования поля, то я не могу ее редактировать, потому что он преобразуется в строку.

Для меня необходим столбец с форматированием в одностороннем порядке (автоматически обновляется) для моего столбца валюты. Но я не могу создать вычисляемый столбец сразу, потому что я использую automapped массив объектов. Я попытался добавить вычисление с использованием примера в http://knockoutjs.com/documentation/plugins-mapping.html, но я не знаю, как его использовать с отображенным массивом.

Мой ViewModel что-то вроде этого:

//--Accounts - Viewmodel Knockout 
function accountViewModel() { 
    var self = this; 
    self.accounts = ko.observableArray(); //this is the list of objects 
    self.account = ko.observable(); //single item for creating or editing 

    //--get list------ 
    self.getAccounts = function() { 
     $.postJSON(appURL + 'Accounts/GetList', function (data) { 
      ko.mapping.fromJS(data.Records, {}, self.accounts); 

     }); 

    }; 

    self.getAccounts(); 
} 

Каждый элемент учетной записи есть поля, такие как: -id -Name -Баланс < - это столбец, я хочу отформатировать

Использование это на странице:

<table data-bind="visible: accounts().length > 0"> 
<thead> 
    <tr> 
     <th scope="col">Id</th> 
     <th scope="col">Name</th> 
     <th scope="col">Balance</th> 
    </tr> 
</thead> 
<tbody id="accounts" data-bind="foreach: accounts"> 
<tr> 
    <td><span data-bind="text: Id"></span></td> 
    <td><a href="" data-bind="text: Name, click: $root.getdetails" style="display:block;"></a></td> 
    <td style="text-align:right;"> 
     <span data-bind="text: formatCurrency(Balance), css: { negative: Balance() < 0, positive: Balance() > 0 }"></span> 

    </td> 
</tr> 
</tbody> 
</table> 

formatCurrency - это просто функция js для formatti ng число:

formatCurrency = function (value) { 
    debugger; 
    if (value!=undefined) 
     return "$" + withCommas(value().toFixed(2)); 
    //had to use value() instead of value, because of toFixed 
} 

Спасибо!

+0

Возможный дубликат использования плагина сопоставления и вычисления на сопоставленном объекте: http://stackoverflow.com/questions/15480316/knockout-dynamic-binding-issue/15480602#15480602 –

ответ

0

Когда вы устанавливаете текст в возвращаемое значение функции (text: formatCurrency(Balance)), он запускается только один раз. Это не наблюдение, поэтому значение никогда больше не будет обновляться. То, что вам нужно, является истинно-синим, вычисленным наблюдаемым. Для этого вам нужно будет настроить сопоставление. Поэтому просто создайте модель представления для вашего индивидуального объекта учетной записи, а затем нарисуйте на ней возвращаемые данные.

var SingleAccountViewModel = function (account) { 
    var model = ko.mapping.fromJS(account); 

    model.FormattedBalance = ko.computed(function() { 
     return formattedCurrency(model.Balance); 
    }); 

    return model; 
} 

Затем, когда вы получите ваши данные от вашего ответа AJAX:

$.postJSON(appURL + 'Accounts/GetList', function (data) { 
    self.accounts($.map(data.Records, SingleAccountViewModel)); 
}); 

Метод jQuery.map будет перебирать массив и возвращает новый массив, состоящий из возвращаемых значений функции передаваемых , В этом случае это ваша модель взгляда, которая теперь будет вычислена на нем FormattedBalance, с которой вы можете привязываться.

+0

Только что реализовано, что теперь Я получил вычисляемую колонку в моей модели. Но FormattedBalance по-прежнему не обновляется при обновлении Баланс – pedroren

+0

Это проблема с использованием foreach с наблюдаемым массивом. Только изменения в самом массиве вызывают обновление, а не изменения объектов * в * массиве. Таким образом, вы должны вызвать изменение массива, чтобы принудительно обновить значение. Ленький способ сделать это - просто получить, а затем установить значение наблюдаемого массива, который будет обновлять весь блок. Этот вопрос SO имеет несколько более утонченный способ сделать это: http://stackoverflow.com/questions/8861106/updating-an-observablearray-does-not-update-ui –

+0

Извините, после реализации вычисленного столбца я не сделал этого, t уведомление, что я получил еще одну ошибку после изменения поля Баланс.Нокаут по какой-то причине преобразовывал его в String, поэтому я получал «объект не имеет метода toFixed» внутри функции formatCurrency. Я разработал его, явно преобразовывая значение в float. Теперь это работает! Благодаря! – pedroren