调用 ko.applyBindings 时出现“无法读取 null 的属性‘nodeType’”
2012-02-03
84225
我有这个 knockout 代码:
function Task(data) {
this.title = ko.observable(data.title);
this.isDone = ko.observable(data.isDone);
}
function TaskListViewModel() {
// Data
var self = this;
self.tasks = ko.observableArray([]);
self.newTaskText = ko.observable();
self.incompleteTasks = ko.computed(function() {
return ko.utils.arrayFilter(self.tasks(), function(task) { return !task.isDone() });
});
// Operations
self.addTask = function() {
self.tasks.push(new Task({ title: this.newTaskText() }));
self.newTaskText("");
};
self.removeTask = function(task) { self.tasks.remove(task) };
}
ko.applyBindings(new TaskListViewModel());
这个 html:
<head>
<script type="text/javascript" src="jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="knockout-2.0.0.js"></script>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<h3>Tasks</h3>
<form data-bind="submit: addTask">
Add task: <input data-bind="value: newTaskText" placeholder="What needs to be done?" />
<button type="submit">Add</button>
</form>
<ul data-bind="foreach: tasks, visible: tasks().length > 0">
<li>
<input type="checkbox" data-bind="checked: isDone" />
<input data-bind="value: title, disable: isDone" />
<a href="#" data-bind="click: $parent.removeTask">Delete</a>
</li>
</ul>
You have <b data-bind="text: incompleteTasks().length"> </b> incomplete task(s)
<span data-bind="visible: incompleteTasks().length == 0"> - it's beer time!</span>
</body>
这个示例与在 Knockout 网站上找到的示例相同,但是当我运行它时,它会在 Chrome Fire Bug 上返回此消息:
Uncaught TypeError: Cannot read property 'nodeType' of null
这个与 knockout 文件和我的脚本的这一行有关:
ko.applyBindings(new TaskListViewModel());
这个错误指向 knockout 上的这一行 (1766):
var isElement = (nodeVerified.nodeType == 1);
我做错了什么?
3个回答
发生此问题的原因是我试图在创建
HTML
元素之前对其进行绑定。
我的脚本加载在
HTML
的顶部(在头部),但它需要加载到我的
HTML
代码的底部(就在结束 body 标签之前)。
感谢您的关注 James Allardice 。
一种可能的解决方法是使用
defer="defer"
<script src="script.js" type="text/javascript" defer="defer"></script>
如果脚本不会生成任何文档内容,请使用此功能。这将告诉浏览器它可以等待内容加载完成后再加载脚本。
进一步阅读 。
希望对您有所帮助。
2012-02-03
您可能要考虑使用 jquery ready 处理程序来实现这一点
$(function() {
function TaskListViewModel() {
...
ko.applyBindings(new TaskListViewModel());
});
然后您可以实现两件事:
- 避免污染全局命名空间
- Knockout 绑定发生在 DOM 创建之后。您可以将 javascript 放置在适合组织的任何位置。
James Kessler
2012-04-12
如果您有 jQuery,请将应用绑定放在
onload
内,以便当 DOM 准备就绪时,knockout 会查找 DOM。
$(document).ready(function(){
ko.applyBindings(new TaskListViewModel());
});
Jhankar Mahbub
2012-12-04