我从服务器收到一个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>


问题是在tbodytd中所有结果都显示在同一行中。

这是我的意思:



它应该创建与recoreds数量一样多的行。为什么会这样呢?我真的不明白我在做什么错。我知道我缺少了一个很小的部分,但是在这一刻我无法发现它。

附言

这是console.log(trackersObjArray());的输出

最佳答案

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

{
    "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对象。有几种选择。

首先,您必须决定是否要


更新服务器代码以立即发送正确的对象结构(首选),或者
保持服务器不变,并在客户端上转换对象。


由于看不到您的服务器代码,因此我选择了选项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绑定。

08-19 15:34