2012-02-03 10 views
92

Mam ten kod nokaut:Pierwsze "nie można odczytać właściwość 'NODETYPE' null" podczas wywoływania 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()); 

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

przykładu jest taki sam, jak ten, znaleźć na stronie internetowej Knockout, ale kiedy go uruchomić, zwraca komunikat o Chrome Straży Bug:

Uncaught TypeError: Cannot read property 'nodeType' of null

Ten jeden jest związany z Knoc Plik kout i do tej linii mojego skryptu:

ko.applyBindings(new TaskListViewModel()); 

I ten błąd jest skierowany do tej linii (1766) na nokaut:

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

Co robię źle?

+0

Ten literówka spowodowałby błąd SyntaxError. Czy naprawienie literówki rozwiązuje problem? –

+0

Yeas ... Zaktualizowałem pytanie, ponieważ przyszedł kolejny błąd. – Gerep

Odpowiedz

165

Ten problem został dzieje, ponieważ starałem się wiązać element HTML zanim został on utworzony.

Mój skrypt został załadowany nad HTML (w głowie), ale musiał być załadowany na dole mojego kodu HTML (tuż przed zamykającym tagiem body).

Dziękuję za uwagę James Allardice.

Możliwe obejście korzysta defer="defer"

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

Użyj tego, jeśli skrypt nie będzie generować żadnych treści dokumentu. To powie przeglądarce, że może czekać na załadowanie zawartości przed załadowaniem skryptu.

Further reading.

Mam nadzieję, że to pomaga.

+4

Aby podkreślić: Znacznik '

5

masz prosty błąd ortograficzny:

self.addTask = fuction() { 

powinno być:

self.addTask = function() { //Notice the added 'n' in 'function' 
32

Można rozważyć użycie jQuery gotowy obsługi dla tego

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

Wtedy można osiągnąć dwie rzeczy:

  1. Unikać zanieczyszczające globalną przestrzeń nazw
  2. Knockout wiązanie występuje po DOM jest stworzony. Możesz umieścić swój javascript wszędzie tam, gdzie nadaje się on do organizacji.

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

+1

Spoiler alert dla tych, którzy nie RTM: '$ (handler)' jest równoważny '$ (dokument) .ready (handler)' –

20

jeśli masz jQuery put zastosować wiązania wewnątrz onload tak, że wygląda na nokaut DOM kiedy DOM jest gotowy.

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

przybity to, btw czy mogę dołączyć inne powiązania na bloku dokumentu? –

+1

Dzięki za informacje! – karthik

Powiązane problemy