为什么foreach没有按预期工作?

时间:2014-06-14 11:12:18

标签: javascript jquery html knockout.js foreach

我从服务器收到json响应,我正在尝试将其映射到可观察数组,然后在HTML表中显示结果。我从服务器得到的是这个字符串:

{"ids":[1,2,3,4],"names":["1","2","test tracker","test1"],"creators":["1","test","test","test"],"projectNames":["1","1","test project","test"]}

现在,我正在尝试在我的视图模型中执行此操作:

我有这个对象应该保存值:

trackersObj = function(item){
         this.trackerId = item.ids;
         this.trackerName = item.names;
         this.trackerCreator = item.creators;
         this.projectNames = item.projectNames;
};

这个ko.observableArray应该保留结果并在表格的正文中循环:

trackersObjArray = ko.observableArray([])

以下是我如何进行映射:

loadActiveTrackers = function () {
    $.ajax({
        type: 'POST',
        url: 'controller.php',
        dataType: 'json',
        data: {
            action: "loadActiveTs"
        },
        success: function (data) {
            trackersObjArray.push(new trackersObj(data));
            console.log(trackersObjArray());
            $('#allTrackers').show();

        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert('Something got wrong!');
        }
    });
};

最后是我的HTML

<table class="dataTable" id="CADataTable">
    <thead>
        <tr>
            <th>Test</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: trackersObjArray">
        <tr>
            <td>
                <input type="text" name="test" data-bind="value: trackerName">
            </td>
        </tr>
    </tbody>
</table>

问题在于tbody的{​​{1}}所有结果都显示在同一行。

这就是我的意思:

Strange foreach issue

它应该创建与recoreds数量一样多的行。为什么会这样?我真的无法理解我做错了什么。我知道我错过了一个超级小部分,但我无法在这个故事中发现它。

P.S。

以下是td

的输出

json structure

1 个答案:

答案 0 :(得分:2)

您的服务器发送多个对象,而不是单个对象。它只是以一种不寻常的方式这样做:

{
    "ids": [1,2,3,4],
    "names": ["1","2","test tracker","test1"],
    "creators": ["1","test","test","test"],
    "projectNames": ["1","1","test project","test"]
}

真的应该是这样的

[
   {"id": 1, "name": "1", "creator": "1", "projectName": "1"}, 
   {"id": 2, "name": "2", "creator": "test", "projectName": "1"}, 
   {"id": 3, "name": "test tracker", "creator": "test", "projectName": "test project"}, 
   {"id": 4, "name": "test1", "creator": "test", "projectName": "test"}
]

因此,您必须循环推送trackersObj个对象。有几种选择。

首先,您必须决定是否要

  1. 更新您的服务器代码以立即发送正确的对象结构(首选)或
  2. 保持服务器不变并转换客户端上的对象。
  3. 由于我没有看到您的服务器代码,我将使用选项2

    loadActiveTrackers = function () {
        $.post('controller.php', {
            action: "loadActiveTs"
        }).then(function (rawData) {
            // transformation step. if you fix your server to send proper data
            // you can drop the entire then().
            var i, transformedData = [];
    
            for (i = 0; i < rawData.ids.length; i++) {
                transformedData.push({
                    id: rawData.ids[i],
                    name: rawData.namess[i],
                    creator: rawData.creators[i],
                    projectName: rawData.projectNames[i]
                });
            }
    
            return transformedData;
        }).done(function (transformedData) {
            ko.utils.arrayForEach(transformedData, function (tracker) {
                trackersObjArray.push(new trackersObj(tracker));
            });
        }).fail(function (XMLHttpRequest, textStatus, errorThrown) {
            alert('Something got wrong!');
        });
    };
    

    这是“手动”方式。您可以不使用for-each循环,而是在一个步骤(trackersObjArray中替换trackersObjArray(transformedData);)的值。您还可以使用映射插件进行更高级的数据到视图模型映射。


    您不应该在视图模型中使用jQuery(或者以任何方式引用DOM),因为这会不必要地将您的视图模型与视图联系起来。依赖应该只是另一种方式。

    换句话说,$('#allTrackers').show();不应该在视图模型中。使用visible绑定。