Ko는 시야에 표시되지 않음을 계산했습니다
-
21-12-2019 - |
문제
계산 된 값에 대한 바인딩에 관한 몇 가지 문제가 있습니다. 나는 테이블에 데이터를 보여주고 일부 필드를 합산하고 있습니다. 바닥 글에서 나는 그 필드의 합계와 빈 열을 표시하고 전체 텍스트가있는 것입니다. 값은 필드 내부에 저장되고 참조 된 필드의 값이 변경되면 업데이트되지만보기에는 표시되지 않습니다. 나는 ko.computed에 뭔가 잘못되었다는 것을 알고 있지만, 그게 무슨 일이 될지 정확하게 찾을 수 없다는 것을 알고 있습니다.
HTML 코드 :
<table>
<caption><h4 class="pull-left">Caption</h4></caption>
<thead>
<tr data-bind="foreach: ColModel">
<th data-bind="text: Caption"></th>
</tr>
</thead>
<tbody data-bind="foreach: { data: model, as: 'row' }">
<tr data-bind="foreach: { data: $root.ColModel, as: 'col' }">
<td data-bind="text: row[col.Field], css: { hidden: col.InSum != false }">
</td>
<td data-bind="css: { hidden: col.InSum != true }">
<input type="number" step="any" class="input-small" data-bind="value:row[col.Field], valueUpdate: 'afterkeydown'" />
</td>
</tr>
</tbody>
<tfoot>
<tr data-bind="foreach: footmodel">
<td data-bind="text: Value">
</td>
</tr>
</tfoot>
</table>
.
Iin My JS가 있습니다
clientViewModel.ColModel = ko.observableArray([
{
Caption: 'cap1',
InSum: false,
Field: 'FLD1'
},
{
Caption: 'cap2',
InSum: false,
Field: 'FLD2'
},
{
Caption: 'capsum1',
InSum: true,
Field: 'fldsum1'
},
{
Caption: 'capsum2',
InSum: true,
Field: 'fldsum2'
}
]);
clientViewModel.model = ko.observableArray();
clientViewModel.footmodel = ko.observableArray([
{
Value: '',
IsSum: false
},
{
Value: 'total',
IsSum: false
},
{
Value: '',
IsSum: true,
SumField: 'fldsum1'
},
{
Value: '',
IsSum: true,
SumField: 'fldsum2'
}
]);
.
Ajax 함수는 프로젝트에서 데이터를 가져 오는 프로젝트에서 사용하는 $ .ajax 함수 주위의 작은 래퍼 일뿐입니다.
ajax('modelurl'),
'GET',
true,
function (data, status) {
$.each(data.Records, function (index, value) {
var observableValue = makeObservable(value, clientViewModel.ColModel);
clientViewModel.model.push(observableValue);
});
$.each(clientViewModel.footmodel(), function (index, value) {
if (value['IsSum']) {
clientViewModel.footmodel()[index]['Value'] = ko.computed(function () {
var sum = 0;
$.each(clientViewModel.model(), function (i, data) {
sum = parseFloat(sum) + parseFloat(data[value['SumField']]());
});
return sum.toString();
}, clientViewModel);
}
else
value['Value'] = ko.observable(value['Value']);
});
});
.
또한 MakeObServable은 객체의 필드를 관찰 할 수있는 필드를 만드는 데 사용됩니다. 알아내는 것처럼 계산에 연결된 모든 필드는 관찰 가능해야하므로 업데이트가 트리거 될 수 있습니다.
function makeObservable(model, fields) {
var ret = {};
$.each(fields(), function (index, value) {
ret[value.Field] = ko.observable(model[value.Field]);
})
return ret;
}
.
무슨 일이 일어나고 있는지 알려지지 않았습니다. FootModel의 관찰 가능한 필드는 계산되지 않고 인쇄되지 않습니다. ClientViewModel.Model Observable Array의 모든 필드는 관찰 가능하므로 값이 계산되지만 인쇄되지 않습니다. 그 이유는 무엇입니까?
하나의 가능한 해결책은 요약 할 값을 계산하고 Observable 필드에 저장할 값을 계산하는 함수를 트리거 할 수 있습니다. 그러나 나는 그것이 이런 식으로 일하고이 행동을 일으키는 것을 알아 내고 있습니다.
감사합니다.
해결책
Ajax 호출 외부의 ko.applyBindings(...)
를 init
<tr data-bind="foreach: footmodel">
<td data-bind="text: Value">
</td>
</tr>
.
text: Value
는 원래의 빈 문자열에 바인딩, Ajax에서 Value
의 내용을 ko.computed(...)
로 바인딩하는 경우, 바인딩 시스템은 알지 못합니다.
이를 고정하려면 if
바인딩을 사용하여 Ajax 뒤에 바인딩 (전체 테이블)을 다시 구문 분석하도록 knockout을 수행합니다.
html
<!-- ko ifnot: loading -->
<table> ... </table>
<!-- /ko -->
.
JS
clientViewModel.loading = ko.observable(false);
// begin ajax
clientViewModel.loading(true); // ko removes the table from DOM
$.ajax({...,
success: function(data, status) {
//... built your ko.computed
},
complete: function() {
// finish ajax
clientViewModel.loading(false); // ko re-creates the table in DOM
}
});
.