문제

계산 된 값에 대한 바인딩에 관한 몇 가지 문제가 있습니다. 나는 테이블에 데이터를 보여주고 일부 필드를 합산하고 있습니다. 바닥 글에서 나는 그 필드의 합계와 빈 열을 표시하고 전체 텍스트가있는 것입니다. 값은 필드 내부에 저장되고 참조 된 필드의 값이 변경되면 업데이트되지만보기에는 표시되지 않습니다. 나는 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
  }
});
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top