Получение "Невозможно прочитать свойство" nodeType "null" при вызове ko.applyBindings
У меня есть этот код нокаута:
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 beer time!</span>
</body>
Пример такой же, как тот, который найден на веб-сайте Knockout, но когда я его запускаю, он возвращает это сообщение в Chrome Fire Bug:
Uncaught TypeError: Невозможно прочитать свойство nodeType 'null
Это связано с файлом нокаута и с этой строкой моего script:
ko.applyBindings(new TaskListViewModel());
И эта ошибка указывает на эту строку (1766) на нокаут:
var isElement = (nodeVerified.nodeType == 1);
Что я делаю неправильно?
Ответы
Ответ 1
Эта проблема произошла, потому что я пытался связать элемент HTML
до его создания.
My script был загружен поверх HTML
(в голове), но его нужно было загрузить в нижней части моего кода HTML
(непосредственно перед тегом закрывающего тела).
Спасибо за внимание Джеймс Аллардис.
Возможным обходным путем является использование defer="defer"
<script src="script.js" type="text/javascript" defer="defer"></script>
Используйте это, если script не будет генерировать содержимое документа. Это скажет браузеру, что он может дождаться загрузки содержимого перед загрузкой script.
Дальнейшее чтение.
Надеюсь, что это поможет.
Ответ 2
Возможно, вы захотите использовать обработчик jquery для этого
$(function() {
function TaskListViewModel() {
...
ko.applyBindings(new TaskListViewModel());
});
Затем вы достигаете двух вещей:
- Избегать загрязнения глобального пространства имен
- Связывание нокаутом происходит после создания DOM. Вы можете разместить свой javascript везде, где он подходит для организации.
См. http://api.jquery.com/ready/
Ответ 3
если у вас есть jQuery, установите привязку привязки внутри onload
, чтобы нокаут искал DOM, когда DOM готов.
$(document).ready(function(){
ko.applyBindings(new TaskListViewModel());
});
Ответ 4
У вас есть простая орфографическая ошибка:
self.addTask = fuction() {
Должно быть:
self.addTask = function() { //Notice the added 'n' in 'function'