Knockout绑定问题$ data显示dataItems存在但$ data.dataItem显示0行

时间:2014-02-27 00:38:55

标签: jquery knockout.js requirejs

我遇到了数据绑定问题。我使用的是knockout-3.0.0.js,require-2.1.11,jquery-1.9.1。

此视图模型中有两个ko.observableArrays。两者都具有相同的数据,并且它们因实现而不同。一个是使用在KnockmeOut上找到的ko.dirtyFlag()模式,另一个是ko.observableArray()计划。

如果我使用计划(self.avail)observableArray,一切都很好。如果我使用KnockMeOut dirtyFlag可观察模式(self.dataItems)没有数据显示。

在HTML输出中:

 Length : <span data-bind="text: dataItems.length"></span>  shows a value of zero

在我的调试中,我发现以下结果令人困惑:

<pre class="hidden3" data-bind="text: ko.toJSON($data, null, 2)"></pre>

显示视图模型中的数据(self.avail)和(self.dataItems)。

在表格列表中:

<tbody data-bind="foreach: dataItems>
    <tr>
        <td><input type="checkbox" /></td>
        <td data-bind="text: id"></td>
     </tr>
</tbody>

0行。

假设我没有ko脚本错误,会导致这种情况发生?

以下是我能想到的最佳细节:

感谢您寻找

查看模型定义

define(['knockout-3.0.0', 'XXXXXMobile/knockoutExt'], function (ko, koExt) {

    var self;


    ko.dirtyFlag = function (root, isInitiallyDirty) {
        var result = function () { },
            _initialState = ko.observable(ko.toJSON(root)),
            _isInitiallyDirty = ko.observable(isInitiallyDirty);

        result.isDirty = ko.computed(function () {
            return _isInitiallyDirty() || _initialState() !== ko.toJSON(root);
        });

        result.reset = function () {
            _initialState(ko.toJSON(root));
            _isInitiallyDirty(false);
        };

        return result;
    };



function Item(id, dId, sId, dF, aF, mF, mId, dc, dm, cb, mb)
{
    this.id = ko.observable(id);
    this.dId = ko.observable(dId);
    this.sId = ko.observable(sId);
    this.dF = ko.observable(dF);
    this.aF = ko.observable(aF);
    this.mF = ko.observable(mF);
    this.mId = ko.observable(mId);
    this.dc = ko.observable(dc);
    this.dm = ko.observable(dm);
    this.cb = ko.observable(cb);
    this.mb = ko.observable(mb);
    this.dirtyFlag = new ko.dirtyFlag(this);
}

function availData(action) {
    $.ajax({
        async: false,
        type: "GET",
        url: action,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (result) {
            console.log("in copy");
            ko.utils.arrayForEach(result, function (r) {
                var ri = new Item(r.ID, r.DEVICE_TYPE_ID, r.SYSTEM_ID, r.DISPLAY_FLAG, r.ACTIVE_FLAG, r.MESSAGE_FLAG, r.MESSAGE_ID, r.DATE_CREATED, r.DATE_MODIFIED, r.CHANGED_BY, r.MODIFIED);
                self.dataItems().push(ri);
            });
            self.avail(result);
        },
        error: function (rsult) {
            console.log(rsult);
        }
    });
}

function availabilityViewModel() {
    self = this;

    self.dataItems = ko.observableArray();
    self.avail = ko.observableArray();

    self.dirtyItems = ko.computed(function () {
        return ko.utils.arrayFilter(self.dataItems(), function (r) {
            return r.dirtyFlag.isDirty();
        });
    }, this);

    self.isDirty = ko.computed(function () {
        return self.dirtyItems().length > 0;
    }, this);


    //self.fetchedData = koExt.asyncDependentObservable(function () {
    //    return $.ajax("/api/CSWAvailability/", {
    //        jsonpCallback: "availabilityResponse",
    //        dataType: "jsonp",
    //        data: { per_page: pageSize }
    //    }).then(function (data) { return data[1]; });
    //}, this);


};


return {
    init: function () {
        availData('/api/CSWAvailability/');

    },
    viewModel: availabilityViewModel
}


});

HTML

Length : <span data-bind="text: dataItems.length"></span>. <br />
<pre class="hidden3" data-bind="text: ko.toJSON($data.dataItems(), null, 2)"></pre>

<div id="x1" class="table table-striped table-hover table-condensed db1Table">
    <table class="table table-striped table-hover table-condensed">
        <thead>
            <tr>
                <th></th>
                <th>#</th>
                <th>Dev</th>
                <th>Module</th>
                <th>Message</th>
                <th>Active</th>
                <th>Disabled</th>
                <th>Show Message</th>

            </tr>
        </thead>


        <tbody data-bind="foreach: dataItems">
            <tr>

                <td><input type="checkbox" /></td>
                <td data-bind="text: id"></td>

            </tr>
        </tbody>

    </table>
</div>

WEBPAGE输出

移动控制开关  显示值/ ID的长度:0。

[]

{
  "dataItems": [
    {
      "id": 100,
      "dId": 100,
      "sId": 1,
      "dF": true,
      "aF": true,
      "mF": false,
      "mId": 1,
      "dc": "2013-02-05T10:01:27",
      "dm": "2014-02-18T09:08:04.23"
    },
    {
      "id": 101,
      "dId": 101,
      "sId": 1,
      "dF": true,
      "aF": true,
      "mF": true,
      "mId": 1,
      "dc": "2013-02-05T10:02:19.167",
      "dm": "2013-05-01T15:34:58.85"
    }


],
  "avail": [
    {
      "ID": 100,
      "DEVICE_TYPE_ID": 100,
      "SYSTEM_ID": 1,
      "DISPLAY_FLAG": true,
      "ACTIVE_FLAG": true,
      "MESSAGE_FLAG": false,
      "MESSAGE_ID": 1,
      "DATE_CREATED": "2013-02-05T10:01:27",
      "DATE_MODIFIED": "2014-02-18T09:08:04.23",
      "CREATED_BY": "rmbAdmin",
      "MODIFIED_BY": "rmbAdmin"
    },
    {
      "ID": 101,
      "DEVICE_TYPE_ID": 101,
      "SYSTEM_ID": 1,
      "DISPLAY_FLAG": true,
      "ACTIVE_FLAG": true,
      "MESSAGE_FLAG": true,
      "MESSAGE_ID": 1,
      "DATE_CREATED": "2013-02-05T10:02:19.167",
      "DATE_MODIFIED": "2013-05-01T15:34:58.85",
      "CREATED_BY": "rmbAdmin",
      "MODIFIED_BY": "rmbAdmin"
    }
  ],
  "dirtyItems": [],
  "isDirty": false
}

#Dev模块消息激活已禁用显示消息

1 个答案:

答案 0 :(得分:2)

这是因为你推送数据的方式。请替换

self.dataItems().push(ri);

使用:

self.dataItems.push(ri);

以下是解释:通过在self.dataItems之后使用括号,您将展开knockout observableArray并返回基础JavaScript数组。通过解开数组,您调用的“push”实现是默认的JavaScript实现,它不会通知任何淘汰观察者添加到数组中的附加项。 Knockout数组操作函数是observableArray的一部分,因此为了使用它们,您不想打开数组。 而且,正如Robert Slaney评论的那样,请确保替换

dataItems.length

dataItems().length