ko.applyBindingsを呼び出すときに「nullのプロパティ 'nodeType'を読み取れません」を取得する


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 Webサイトにあるものと同じですが、実行すると、Chrome Fire Bugで次のメッセージが返されます。

Uncaught TypeError:nullのプロパティ 'nodeType'を読み取れません

これはノックアウトファイルと私のスクリプトの次の行に関連しています。

ko.applyBindings(new TaskListViewModel());

そして、このエラーはノックアウトのこの行(1766)を指しています:

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

何が悪いのですか?


そのタイプミスにより、SyntaxErrorが発生します。タイプミスを修正することで問題は解決しますか?
James Allardice

はい...別のエラーが発生したため、質問を更新しました。
Gerep

回答:


176

HTML作成前に要素をバインドしようとしたため、この問題が発生していました。

私のスクリプトはHTML(頭の中で)上にロードされましたが、HTMLコードの下部(本文の終了タグの直前)にロードする必要がありました。

ジェームス・アラディス様静聴ありがとうございました。

可能な回避策は defer="defer"

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

スクリプトがドキュメントコンテンツを生成しない場合は、これを使用します。これは、スクリプトをロードする前にコンテンツがロードされるのを待つことができることをブラウザに伝えます。

また、読書

それが役に立てば幸い。


4
強調するには:<script ...>タグはページの下部、終了</body>タグの直前にある必要があります。
aliteralmind 2014

1
素晴らしい、ありがとう!スクリプトを本文の最後に移動しただけで、完全に機能しました。多くの感謝
Eleanor Zimmermann

33

このためにjquery readyハンドラーの使用を検討してください

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

次に、2つのことを実現します。

  1. グローバル名前空間を汚染しない
  2. ノックアウトバインディングは、DOMが作成された後に発生します。組織に適した場所であればどこでもJavaScriptを配置できます。

http://api.jquery.com/ready/を参照してください


1
RTMを行わなかった人のためのスポイラーアラート:$(handler)に相当$(document).ready(handler)
ブロックヘンスリー2013

21

jQueryを使用している場合onloadは、DOMの準備ができたときにノックアウトがDOMを探すように、内部にapplyバインディングを配置します。

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

釘付けになりましたが、ドキュメントブロックに他のバインディングを含めることはできますか?
アランジカム2013年

1
あなたの情報をありがとう!!
karthik 2013

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.