Ko.applyBindings çağrılırken "null 'nodeType' özelliği okunamıyor" mesajı alınıyor


99

Bu nakavt koduna sahibim:

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

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

Örnek, Knockout web sitesinde bulunanla aynıdır, ancak onu çalıştırdığımda Chrome Fire Bug'da şu mesajı döndürür:

Yakalanmamış TypeError: null 'nodeType' özelliği okunamıyor

Bu, nakavt dosyasıyla ve komut dosyamın şu satırıyla ilgilidir:

ko.applyBindings(new TaskListViewModel());

Ve bu hata nakavtta şu satırı (1766) işaret ediyor:

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

Neyi yanlış yapıyorum?


Bu yazım hatası sözdizimi Hatasına neden olur. Yazım hatasını düzeltmek sorunu çözüyor mu?
James Allardice

Evet ... Soruyu güncelledim çünkü başka bir hata geldi.
Gerep

Yanıtlar:


176

Bu sorun oluşuyordu çünkü HTMLyaratılmadan önce bir öğeyi bağlamaya çalışıyordum .

Komut dosyam HTML(başlığın içine) üstüne yüklendi, ancak kodumun altına HTML(kapanış gövde etiketinden hemen önce) yüklenmesi gerekiyordu .

İlginiz için teşekkürler James Allardice .

Olası bir geçici çözüm kullanıyor defer="defer"

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

Komut dosyası herhangi bir belge içeriği oluşturmayacaksa bunu kullanın. Bu, tarayıcıya komut dosyasını yüklemeden önce içeriğin yüklenmesini bekleyebileceğini söyleyecektir.

Daha fazla okuma .

Umarım yardımcı olur.


4
Vurgulamak için: <script ...>Etiket, sayfanın alt kısmında, kapanış </body>etiketinin hemen öncesinde olmalıdır .
aliteralmind

1
harika, teşekkürler! Senaryomu vücudun sonuna taşıdım ve mükemmel çalıştı. birçok minnettarlık
Eleanor Zimmermann

33

Bunun için jquery hazır işleyicisini kullanmayı düşünebilirsiniz

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

O zaman iki şeye ulaşırsınız:

  1. Küresel ad alanını kirletmekten kaçının
  2. Altını gizleme bağlama, DOM oluşturulduktan sonra gerçekleşir. Javascript'inizi organizasyon için uygun olan yere yerleştirebilirsiniz.

Bkz. Http://api.jquery.com/ready/


1
RTM yapmayanlar için spoiler uyarısı: $(handler)eşdeğerdir$(document).ready(handler)
Brock Hensley

21

jQuery varsa, içeri onloadatma işlemi DOM hazır olduğunda DOM'u arar.

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

çivilenmiş, btw belge bloğuna diğer bağlamaları ekleyebilir miyim?
Allan Jikamu

1
Bilgi için teşekkürler!!
karthik

5

Basit bir yazım hatanız var:

self.addTask = fuction() {

Olmalı:

self.addTask = function() { //Notice the added 'n' in 'function'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.