web-dev-qa-db-fra.com

Obtenir "Ne peut pas lire la propriété 'nodeType' de null" lors de l'appel de ko.applyBindings

J'ai ce code KO:

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());

Ce 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>

L'exemple est le même que celui trouvé sur le site Web Knockout, mais lorsque je l'exécute, il renvoie ce message sur Chrome Bogue incendie:

Uncaught TypeError: impossible de lire la propriété 'nodeType' de null

Celui-ci est lié au fichier knockout et à cette ligne de mon script:

ko.applyBindings(new TaskListViewModel());

Et cette erreur pointe vers cette ligne (1766) sur KO:

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

Qu'est-ce que je fais mal?

99
Gerep

Ce problème se produisait parce que j'essayais de lier un élément HTML avant sa création.

Mon script a été chargé par-dessus le HTML (dans la tête), mais il devait l'être au bas de mon code HTML (juste avant la balise body de fermeture).

Merci de votre attention James Allardice .

Une solution possible consiste à utiliser defer="defer"

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

Utilisez cette option si le script ne génère aucun contenu de document. Cela indiquera au navigateur qu'il peut attendre que le contenu soit chargé avant de charger le script.

Lectures complémentaires .

J'espère que ça aide.

175
Gerep

Vous voudrez peut-être envisager d’utiliser le gestionnaire jquery ready pour cette commande.

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

Ensuite, vous réalisez deux choses:

  1. Évitez de polluer l'espace de noms global
  2. La liaison knockout se produit APRÈS la création du DOM. Vous pouvez placer votre javascript partout où il convient à l'organisation.

Voir http://api.jquery.com/ready/

33
James Kessler

si vous avez jQuery, mettez une liaison dans onload afin que knockout recherche le DOM quand celui-ci est prêt.

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

Vous avez une simple faute d'orthographe:

self.addTask = fuction() {

Devrait être:

self.addTask = function() { //Notice the added 'n' in 'function'
5
James Allardice