Отримання "Неможливо прочитати властивість 'nodeType' null" під час виклику ko.applyBindings


99

У мене є цей код нокауту:

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">&nbsp;</b> incomplete task(s)
    <span data-bind="visible: incompleteTasks().length == 0"> - it's beer time!</span>
</body>

Приклад такий самий, як той, який знайдено на веб-сайті Knockout, але коли я запускаю його, він повертає це повідомлення на Chrome Fire Bug:

Uncaught TypeError: Неможливо прочитати властивість 'nodeType' null

Цей пов'язаний з файлом нокауту та цим рядком мого сценарію:

ko.applyBindings(new TaskListViewModel());

І ця помилка вказує на цю лінію (1766) у нокауті:

var isElement = (nodeVerified.nodeType == 1);

Що я роблю неправильно?


Цей друкарський помилок спричинить цей SyntaxError. Чи виправлення помилки друкує проблему?
Джеймс Аллардіс

Yeas ... Я оновив питання, оскільки сталася ще одна помилка.
Гереп

Відповіді:


176

Ця проблема трапилася тому, що я намагався зв’язати HTMLелемент ще до його створення.

Мій сценарій був завантажений вгорі HTML(у голові), але його потрібно було завантажити внизу мого HTMLкоду (безпосередньо перед закриваючим тегом body).

Дякую за увагу Джеймсу Аллардісу .

Можливе вирішення питань використання defer="defer"

<script src="script.js" type="text/javascript" defer="defer"></script>

Використовуйте це, якщо сценарій не збирається створювати будь-який вміст документа. Це скаже браузеру, що він може чекати завантаження вмісту перед завантаженням сценарію.

Подальше читання .

Сподіваюся, це допомагає.


4
Щоб підкреслити: <script ...>Тег повинен бути внизу сторінки, безпосередньо перед закритим </body>тегом.
aliteralmind

1
чудово, дякую! Я просто перемістив свій сценарій до кінця тексту, і він прекрасно працював. багато подяк
Елеонора Циммерманн

33

Ви можете розглянути можливість використання для цього обробника jquery ready

$(function() {
   function TaskListViewModel() {
   ...
   ko.applyBindings(new TaskListViewModel());
});

Тоді ви досягаєте двох речей:

  1. Уникайте забруднення глобального простору імен
  2. Прив'язка нокауту відбувається ПІСЛЯ створення DOM. Ви можете розмістити свій JavaScript там, де він підходить для організації.

Дивіться http://api.jquery.com/ready/


1
Оповіщення про спойлер для тих, хто не здійснював RTM: $(handler)еквівалентно$(document).ready(handler)
Броку Хенслі

21

якщо у вас є jQuery, застосуйте прив'язку всередині, onloadщоб нокаут шукав DOM, коли DOM буде готовий.

$(document).ready(function(){
    ko.applyBindings(new TaskListViewModel());
});

прибити її, btw чи можу я включити інші прив'язки до блоку документа?
Аллан Джікаму

1
Дякуємо за вашу інформацію !!
karthik

5

Ви маєте просту орфографічну помилку:

self.addTask = fuction() {

Має бути:

self.addTask = function() { //Notice the added 'n' in 'function'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.