Mendapatkan "Cannot read property 'nodeType' of null" saat memanggil ko.applyBindings

99

Saya memiliki kode sistem gugur ini:

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 ini:

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

Contohnya sama dengan yang ditemukan di situs web Knockout, tetapi ketika saya menjalankannya, ini mengembalikan pesan ini di Chrome Fire Bug:

TypeError Tidak Tertangkap: Tidak dapat membaca properti 'nodeType' dari null

Yang ini terkait dengan file knockout dan baris skrip saya ini:

ko.applyBindings(new TaskListViewModel());

Dan kesalahan ini menunjuk ke baris ini (1766) saat KO:

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

Apa yang saya lakukan salah?

Gerep
sumber
Kesalahan ketik itu akan menyebabkan SyntaxError itu. Apakah memperbaiki kesalahan ketik dapat memperbaiki masalah?
James Allardice
Ya ... Saya telah memperbarui pertanyaan karena kesalahan lain datang.
Gerep

Jawaban:

176

Masalah ini terjadi karena saya mencoba mengikat HTMLelemen sebelum dibuat.

Skrip saya dimuat di atas HTML(di kepala) tetapi harus dimuat di bagian bawah HTMLkode saya (tepat sebelum tag body penutup).

Terima kasih atas perhatian Anda James Allardice .

Sebuah solusi yang mungkin digunakan defer="defer"

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

Gunakan ini jika skrip tidak akan menghasilkan konten dokumen apa pun. Ini akan memberi tahu browser bahwa ia dapat menunggu konten dimuat sebelum memuat skrip.

Bacaan lebih lanjut .

Semoga membantu.

Gerep
sumber
4
Untuk menekankan: <script ...>Tag harus berada di bagian bawah halaman, tepat sebelum </body>tag penutup.
aliteralmind
1
luar biasa, terima kasih! Saya baru saja memindahkan skrip saya ke ujung badan dan itu bekerja dengan sempurna. banyak terima kasih
Eleanor Zimmermann
33

Anda mungkin ingin mempertimbangkan untuk menggunakan jquery ready handler untuk ini

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

Kemudian Anda mencapai dua hal:

  1. Hindari mencemari namespace global
  2. Knockout binding terjadi SETELAH DOM dibuat. Anda dapat menempatkan javascript Anda dimanapun itu cocok untuk pengaturan.

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

James Kessler
sumber
1
Peringatan spoiler untuk mereka yang tidak RTM: $(handler)setara dengan$(document).ready(handler)
Brock Hensley
21

jika Anda memiliki jQuery, taruh apply binding di dalamnya onloadsehingga knockout mencari DOM saat DOM sudah siap.

$(document).ready(function(){
    ko.applyBindings(new TaskListViewModel());
});
Jhankar Mahbub
sumber
berhasil, btw dapatkah saya menyertakan binding lain di blok dokumen?
Allan Jikamu
1
Terima kasih atas info Anda !!
karthik
5

Anda memiliki kesalahan ejaan sederhana:

self.addTask = fuction() {

Seharusnya:

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