รับ "ไม่สามารถอ่านคุณสมบัติ 'nodeType' ของ null" เมื่อเรียก ko.applyBindings


99

ฉันมีรหัสที่น่าพิศวงนี้:

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 นี้:

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

ตัวอย่างนี้เหมือนกับตัวอย่างที่พบในเว็บไซต์ Knockout แต่เมื่อฉันเรียกใช้มันจะส่งคืนข้อความนี้ใน Chrome Fire Bug:

Uncaught TypeError: ไม่สามารถอ่านคุณสมบัติ 'nodeType' ของ null

อันนี้เกี่ยวข้องกับไฟล์สิ่งที่น่าพิศวงและกับสคริปต์ของฉันบรรทัดนี้:

ko.applyBindings(new TaskListViewModel());

และข้อผิดพลาดนี้ชี้ไปที่บรรทัดนี้ (1766) เมื่อน็อคเอาท์:

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

ผมทำอะไรผิดหรือเปล่า?


การพิมพ์ผิดนั้นจะทำให้เกิด SyntaxError นั้น การแก้ไขการพิมพ์ผิดช่วยแก้ปัญหาได้หรือไม่
James Allardice

ใช่ ... ฉันได้อัปเดตคำถามเนื่องจากมีข้อผิดพลาดอื่นเกิดขึ้น
Gerep

คำตอบ:


176

ปัญหานี้เกิดขึ้นเนื่องจากฉันพยายามผูกHTMLองค์ประกอบก่อนที่จะสร้าง

สคริปต์ของฉันถูกโหลดที่ด้านบนของHTML(ในส่วนหัว) แต่จำเป็นต้องโหลดที่ด้านล่างของHTMLโค้ดของฉัน(ก่อนแท็กเนื้อหาปิด)

ขอบคุณสำหรับความสนใจของคุณเจมส์ Allardice

วิธีแก้ปัญหาที่เป็นไปได้กำลังใช้ defer="defer"

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

ใช้สิ่งนี้หากสคริปต์ไม่ได้สร้างเนื้อหาเอกสารใด ๆ สิ่งนี้จะบอกเบราว์เซอร์ว่าสามารถรอให้เนื้อหาโหลดได้ก่อนที่จะโหลดสคริปต์

อ่านเพิ่มเติม

หวังว่าจะช่วยได้


4
เพื่อเน้นย้ำ: <script ...>แท็กจะต้องอยู่ที่ด้านล่างของหน้าก่อน</body>แท็กปิด
aliteralmind

1
ยอดเยี่ยมขอบคุณ! ฉันเพิ่งย้ายสคริปต์ไปที่ส่วนท้ายของเนื้อหาและทำงานได้อย่างสมบูรณ์ ความพึงพอใจมากมาย
Eleanor Zimmermann

33

คุณอาจต้องการพิจารณาใช้ตัวจัดการพร้อม jquery สำหรับสิ่งนี้

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

จากนั้นคุณจะบรรลุสองสิ่ง:

  1. หลีกเลี่ยงการสร้างมลพิษให้กับเนมสเปซทั่วโลก
  2. การผูกสิ่งที่น่าพิศวงเกิดขึ้นหลังจากสร้าง DOM คุณสามารถวางจาวาสคริปต์ได้ทุกที่ที่เหมาะกับองค์กร

ดูhttp://api.jquery.com/ready/


1
การแจ้งเตือนสปอยเลอร์สำหรับผู้ที่ไม่ได้ RTM: $(handler)เทียบเท่ากับ$(document).ready(handler)
Brock Hensley

21

หากคุณมี jQuery ให้ใช้การผูกภายในonloadเพื่อให้สิ่งที่น่าพิศวงมองหา DOM เมื่อ DOM พร้อม

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

ตอกแล้ว btw ฉันสามารถรวมการผูกอื่น ๆ ในบล็อกเอกสารได้หรือไม่?
Allan Jikamu

1
ขอบคุณสำหรับข้อมูล !!
karthik

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.