【问题标题】:ko computed not showing in viewko 计算未显示在视图中
【发布时间】:2014-09-22 13:08:22
【问题描述】:

我有一些关于绑定到计算值的问题。我在表格中显示数据,并总结了一些字段。在页脚中,我想显示这些字段的总和,以及空列,以及带有总计文本的列。这些值存储在字段内,并在引用字段的值更改时更新,但它不会显示在视图中。我知道我对 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 可观察数组的所有字段都是可观察的,值被计算出来,但它们不会被打印出来。这是什么原因?

据我所知,一种可能的解决方案可能是触发计算要求和的值并将其存储在可观察字段中的函数,这应该可以打印出来。但我宁愿让它以这种方式工作,并找出导致这种行为的原因。

谢谢。

【问题讨论】:

  • 你能用你的问题做一个 jsFiddle 吗?我发现这很难理解。

标签: knockout.js knockout-2.0 computed-observable


【解决方案1】:

我猜你在 ajax 调用之外初始化 ko.applyBindings(...),这意味着

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

text: Value绑定到原来的空字符串,即使你用ko.computed(...)替换ajax中Value的内容,绑定系统也不知道。

要修复它,请使用if 绑定强制敲除以在ajax 之后重新解析绑定(整个表)。

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

【讨论】:

  • 嘿伙计。谢谢,这真的有效。我在开始时将加载设置为 false,当我开始获取数据时将其设置为 true,当我在最后一个 ajax 调用中完成加载数据时,我再次将其设置为 false。我会支持你,但我的代表太低了,所以其他人将不得不:)
  • 是的,忘记了,抱歉,急忙在测试服务器上设置它:) 现在它已修复:)
猜你喜欢
  • 2019-09-01
  • 1970-01-01
  • 2013-12-11
  • 2021-02-17
  • 2013-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-08
相关资源
最近更新 更多