Ottenere "Impossibile leggere la proprietà 'nodeType' di null" durante la chiamata a ko.applyBindings


99

Ho questo codice 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());

Questo 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'esempio è lo stesso trovato sul sito Web di Knockout, ma quando lo eseguo, restituisce questo messaggio su Chrome Fire Bug:

TypeError non rilevato: impossibile leggere la proprietà "nodeType" di null

Questo è correlato al file knockout ea questa riga del mio script:

ko.applyBindings(new TaskListViewModel());

E questo errore punta a questa linea (1766) su knockout:

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

Che cosa sto facendo di sbagliato?


Quel refuso causerebbe quell'errore SyntaxError. La correzione dell'errore di battitura risolve il problema?
James Allardice

Sì ... ho aggiornato la domanda perché è arrivato un altro errore.
Gerep

Risposte:


176

Questo problema si verificava perché stavo cercando di associare un HTMLelemento prima che fosse creato.

Il mio script è stato caricato sopra HTML(in testa) ma doveva essere caricato in fondo al mio HTMLcodice (appena prima del tag di chiusura del corpo).

Grazie per la tua attenzione James Allardice .

Una possibile soluzione alternativa sta usando defer="defer"

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

Usalo se lo script non genererà alcun contenuto del documento. Questo indicherà al browser che può attendere il caricamento del contenuto prima di caricare lo script.

Ulteriore lettura .

Spero che sia d'aiuto.


4
Per sottolineare: il <script ...>tag deve essere nella parte inferiore della pagina, subito prima del </body>tag di chiusura .
aliteralmind

1
meraviglioso, grazie! Ho appena spostato il mio copione alla fine del corpo e ha funzionato perfettamente. molte gratitudini
Eleanor Zimmermann

33

Potresti prendere in considerazione l'utilizzo del gestore jquery ready per questo

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

Quindi ottieni due cose:

  1. Evita di inquinare lo spazio dei nomi globale
  2. L'associazione knockout si verifica DOPO la creazione del DOM. Puoi posizionare il tuo javascript ovunque sia adatto per l'organizzazione.

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


1
Avviso spoiler per chi non ha fatto RTM: $(handler)equivale a$(document).ready(handler)
Brock Hensley

21

se hai jQuery inserisci il binding all'interno in onloadmodo che knockout cerchi il DOM quando il DOM è pronto.

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

inchiodato, btw posso includere altre associazioni sul blocco del documento?
Allan Jikamu

1
Grazie per le tue informazioni !!
karthik

5

Hai un semplice errore di ortografia:

self.addTask = fuction() {

Dovrebbe essere:

self.addTask = function() { //Notice the added 'n' in 'function'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.