Observable数组不会在前端向我的表提供数据

时间:2015-10-25 02:46:23

标签: javascript knockout.js

的index.html:

<!DOCTYPE html>
<html>
<head>
    <title>SequoiaCG</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <script src="assets/js/jquery-1.11.3.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="knockout-3.3.0.js"></script>
</head>
<body>
    <script src="assets/js/testing.js"></script>
    <table>
        <thead><tr>
            <th>First name</th><th>Last name</th>
        </tr></thead>
        <tbody data-bind="foreach: contactGrid">
            <tr>
                <td data-bind="text: firstName"></td>
                <td data-bind="text: lastName"></td>
            </tr>
        </tbody>
    </table>
</body>
</html>

testing.js:

function contact(fName, lName) {
    var self = this;
    self.firstName = fName;
    self.lastName = lName;
}

function contactsViewModel() {
    var self = this;

    self.contactGrid = ko.observableArray([
        new contact("Bob", "Marley"),
        new contact("Testing", "123")
        ]);
}

ko.applyBindings(new contactsViewModel());

我试图将引用移到HTML文件中的testing.js更高,因为我认为可能在JS文件有机会运行之前编写了表。但看起来这并没有什么不同。如果我把它放得太高,我就会收到错误。如果我将它作为HTML正文标记中的第一项,它仍然不会显示任何结果。我想知道我是否错过了与Knockout.js正确数据绑定的步骤?我很感激任何提示。

1 个答案:

答案 0 :(得分:1)

您发布的代码存在的问题是,您可能在DOM准备好之前调用ko.applyBindings,例如在浏览器甚至知道table之前。试着这样做:

document.addEventListener("DOMContentLoaded", function(event) {
    // Add `testing.js` contents here.
});

或者使用jQuery实现更好的跨浏览器兼容:

$(function() {
    // Add `testing.js` contents here.
});

请注意,只有applyBindings技术上需要延迟到DOM加载之后,你发布的其他位在此之前就没问题了。

如果您使用像the one @dotnetom posted in a comment这样的jsfiddle,默认情况下代码也会执行onLoad(请参阅左上角的“框架和扩展”设置)。如果您将默认值更改为接近您在问题中描述的情况(在头部分中加载脚本),则会遇到与您描述的问题相同的问题:请参阅this fiddle

最终的“修复”也可能是@Dandy建议的那个,即将script标记放在相关的DOM位之下。但是,如果可能的话,我建议更明确,不要在DOM加载上述方法之前解雇你的代码。