Frage

Ich habe einige Probleme mit der Bindung an den berechneten Wert.Ich zeige Daten in einer Tabelle und fasse einige Felder zusammen.In der Fußzeile möchte ich die Summe dieser Felder und die leere Spalte sowie eine mit dem Gesamttext anzeigen.Die Werte werden in den Feldern gespeichert und aktualisiert, wenn sich der Wert der referenzierten Felder ändert, sie werden jedoch nicht in der Ansicht angezeigt.Ich weiß, dass ich mit ko.computed etwas falsch gemacht habe, aber ich kann nicht genau sagen, was das sein könnte.

HTML Quelltext:

    <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>

In meinem JS habe ich

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'
    }
]);

Die Ajax-Funktion ist nur ein kleiner Wrapper um die $.ajax-Funktion, die wir im Projekt zum Abrufen von Daten verwenden.

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']);
        });
});

Außerdem wird makeObservable verwendet, um die Felder eines Objekts beobachtbar zu machen.Wie ich herausgefunden habe, sollten alle mit der Berechnung verbundenen Felder beobachtbar sein, sodass die Aktualisierung ausgelöst werden kann.

function makeObservable(model, fields) {
    var ret = {};
    $.each(fields(), function (index, value) {
        ret[value.Field] = ko.observable(model[value.Field]);
    })
    return ret;
}

Was los ist, ist mir unbekannt.Beobachtbare Felder des Fußmodells werden ausgedruckt, berechnete jedoch nicht.Alle Felder des beobachtbaren Arrays clientViewModel.model sind beobachtbar, die Werte werden berechnet, aber nicht ausgedruckt.Was ist der Grund dafür?

Eine mögliche Lösung könnte meiner Meinung nach darin bestehen, die Funktion auszulösen, die die zu summierenden Werte berechnet und im beobachtbaren Feld speichert, das in Ordnung ausgedruckt werden sollte.Aber ich würde es lieber so machen und herausfinden, was dieses Verhalten verursacht.

Danke.

War es hilfreich?

Lösung

Ich schätze, du hast es initiiert ko.applyBindings(...) außerhalb des Ajax-Aufrufs, was bedeutet

<tr data-bind="foreach: footmodel">
    <td data-bind="text: Value"> 
    </td>
</tr>

Der text: Value bindet an die ursprüngliche leere Zeichenfolge, auch wenn Sie den Inhalt ersetzen Value in Ajax mit a ko.computed(...), das Bindungssystem weiß es nicht.

Um das Problem zu beheben, verwenden Sie eine if Bindung, um Knockout zu erzwingen, um die Bindung (die gesamte Tabelle) nach Ajax erneut zu analysieren.

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
  }
});
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top