سؤال

لدي بعض المشاكل فيما يتعلق بالربط بالقيمة المحسوبة.أقوم بعرض البيانات في الجدول، وتلخيص بعض الحقول.أريد في التذييل عرض مجموع هذه الحقول والعمود الفارغ بالإضافة إلى العمود الذي يحتوي على نص الإجمالي.يتم تخزين القيم داخل الحقول، بالإضافة إلى تحديثها عندما تتغير قيمة الحقول المشار إليها، ولكنها لا تظهر في طريقة العرض.أعلم أنني ارتكبت خطأً ما في 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>

لدي في 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;
}

ما يحدث غير معروف بالنسبة لي.تتم طباعة الحقول التي يمكن ملاحظتها من نموذج القدم، في حين لا يتم حسابها.جميع حقول المصفوفة القابلة للملاحظة ClientViewModel.model يمكن ملاحظتها، ويتم حساب القيم، لكن لا تتم طباعتها.ما هو السبب في ذلك؟

أحد الحلول الممكنة، بقدر ما أرى، يمكن أن يكون تشغيل الوظيفة التي تحسب القيم المراد جمعها وتخزينها في الحقل الذي يمكن ملاحظته، والذي يجب أن تتم طباعته بشكل جيد.لكنني أفضل أن أجعل الأمر يعمل بهذه الطريقة، وأكتشف أسباب هذا السلوك.

شكرًا.

هل كانت مفيدة؟

المحلول

أعتقد أنك الحرف الأول ko.applyBindings(...) خارج مكالمة اياكس، وهو ما يعني

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

ال text: Value يرتبط بالسلسلة الفارغة الأصلية، حتى إذا قمت باستبدال محتوى ملف Value في اياكس مع أ ko.computed(...), ، نظام الربط لا يعرف.

لإصلاحه، استخدم if الربط لإجبار الضربة القاضية على إعادة تحليل الارتباط (الجدول بأكمله) بعد ajax.

لغة البرمجة

<!-- ko ifnot: loading -->
  <table> ... </table>
<!-- /ko -->

شبيبة

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