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

标签 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"]}

现在这是我在我的 View 模型中尝试做的事情:

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

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 中,所有结果都显示在同一行中。

我的意思是:

Strange foreach issue

它应该创建与记录数一样多的行。为什么会这样?我真的不明白我做错了什么。我知道我遗漏了一个非常小的部分,但我现在无法发现它。

附言

这是 console.log(trackersObjArray());

的输出

json structure

最佳答案

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

{
    "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. 让服务器保持原样,并在客户端转换对象。

因为我没有看到您的服务器代码,所以我选择选项 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(transformedData);) 中替换 trackersObjArray 的值。您还可以使用映射插件进行更高级的数据到 View 模型映射。


您不应该在您的 View 模型中使用 jQuery(或以任何方式引用 DOM),因为这会不必要地将您的 View 模型绑定(bind)到您的 View 。依赖关系应该只是相反的方式。

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

关于javascript - 为什么 foreach 没有按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24219335/

相关文章:

javascript - 将连接的结果集拆分为行

javascript - 清除 Fine Uploader 中的文件列表,以便仅重新上传一个文件

javascript - 使用javascript强制图像缓存

jquery - 边框颜色混合

jquery - 使用 jquery 添加图像

javascript - eval_in_page javascript 执行在 firefox 中有效,但在 phantomjs 中无效

javascript - 如何识别由于 Chrome 扩展而导致的 DOM html 代码更改

javascript - 单击父元素时 jQuery 在子元素中淡入淡出

php - 禁用聪明的通知

html - 在页面中嵌入 PDF 字节流的问题