it-swarm.com.de

Beim Aufrufen von ko.applyBindings wird die Meldung "Die Eigenschaft 'nodeType' von null kann nicht gelesen werden" ausgegeben

Ich habe diesen KO-Code:

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

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

Das Beispiel ist das gleiche wie das auf der Knockout-Website, aber wenn ich es ausführe, wird diese Meldung am Chrome Fire Bug:

Nicht erfasster TypeError: Die Eigenschaft 'nodeType' von null kann nicht gelesen werden

Dieser bezieht sich auf die Knockout-Datei und auf diese Zeile meines Skripts:

ko.applyBindings(new TaskListViewModel());

Und dieser Fehler zeigt auf diese Zeile (1766) beim Knockout:

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

Was mache ich falsch?

99
Gerep

Dieses Problem ist aufgetreten, weil ich versucht habe, ein HTML -Element zu binden, bevor es erstellt wurde.

Mein Skript wurde über dem HTML (im Kopf) geladen, aber es musste am Ende meines HTML Codes (kurz vor dem schließenden Body-Tag) geladen werden.

Vielen Dank für Ihre Aufmerksamkeit James Allardice .

Eine mögliche Problemumgehung ist die Verwendung von defer="defer"

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

Verwenden Sie diese Option, wenn das Skript keinen Dokumentinhalt generiert. Dies teilt dem Browser mit, dass er warten kann, bis der Inhalt geladen ist, bevor das Skript geladen wird.

Weiterführende Literatur .

Ich hoffe es hilft.

175
Gerep

Möglicherweise möchten Sie den jquery ready-Handler verwenden

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

Dann erreichen Sie zwei Dinge:

  1. Vermeiden Sie es, den globalen Namespace zu verschmutzen
  2. Die Knockout-Bindung erfolgt, nachdem das DOM erstellt wurde. Sie können Ihr Javascript dort platzieren, wo es für die Organisation geeignet ist.

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

33
James Kessler

wenn Sie jQuery verwenden, wenden Sie Binding in onload an, damit Knockout nach dem DOM sucht, wenn DOM bereit ist.

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

Sie haben einen einfachen Rechtschreibfehler:

self.addTask = fuction() {

Sollte sein:

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