web-dev-qa-db-ger.com

"Uncaught TypeError: undefined ist keine Funktion" - Beginner Backbone.js Application

Ich richte eine ziemlich einfache App mit Backbone ein und erhalte eine Fehlermeldung.

Uncaught TypeError: undefined is not a function example_app.js:7
ExampleApp.initialize example_app.js:7
(anonymous function)

Hier wird der Fehler in Chrome Inspector (Init-Datei - example_app.js) angezeigt:

var ExampleApp = {
  Models: {},
  Collections: {},
  Views: {},
  Routers: {},
  initialize: function() {
    var tasks = new ExampleApp.Collections.Tasks(data.tasks);
    new ExampleApp.Routers.Tasks({ tasks: tasks });
    Backbone.history.start();
  }
};

Hier ist meine Tasks index.haml-Datei

- content_for :javascript do
  - javascript_tag do
    ExampleApp.initialize({ tasks: #{raw @tasks.to_json} });

= yield :javascript

models/task.js

var Task = Backbone.Model.extend({});

collections/tasks.js

var Tasks = Backbone.Collection.extend({
    model: Task,
    url: '/tasks'
});

routers/tasks.js

ExampleApp.Routers.Tasks = Backbone.Router.extend({
    routes: {
        "": "index"
    },

    index: function() {
        alert('test');
        // var view = new ExampleApp.Views.TaskIndex({ collection: ExampleApp.tasks });
        // $('body').html(view.render().$el);
    }
});

Und hier ist der Beweis, dass ich alle Dateien aufrufe (glaube ich):

<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery-ui.js?body=1" type="text/javascript"></script>
<script src="/assets/underscore.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone-support/support.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone-support/composite_view.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone-support/swapping_router.js?body=1" type="text/javascript"></script>
<script src="/assets/backbone-support.js?body=1" type="text/javascript"></script>
<script src="/assets/example_app.js?body=1" type="text/javascript"></script>
<script src="/assets/easing.js?body=1" type="text/javascript"></script>
<script src="/assets/modernizr.js?body=1" type="text/javascript"></script>
<script src="/assets/models/task.js?body=1" type="text/javascript"></script>
<script src="/assets/collections/tasks.js?body=1" type="text/javascript"></script>
<script src="/assets/views/task_view.js?body=1" type="text/javascript"></script>
<script src="/assets/views/tasks.js?body=1" type="text/javascript"></script>
<script src="/assets/views/tasks_index.js?body=1" type="text/javascript"></script>
<script src="/assets/routers/tasks.js?body=1" type="text/javascript"></script>
<script src="/assets/tasks/index.js?body=1" type="text/javascript"></script>
<script src="/assets/tasks/task.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>

Irgendwelche Ideen wären toll. Vielen Dank!

38
jake

Nicht erfasster TypeError: undefined ist keine Funktion example_app.js: 7

Diese Fehlermeldung erzählt die ganze Geschichte. In dieser Zeile versuchen Sie, eine Funktion auszuführen. Was auch immer ausgeführt wird, ist keine Funktion! Stattdessen ist es undefined.

Was steht also in example_app.js Zeile 7? Sieht aus wie das:

var tasks = new ExampleApp.Collections.Tasks(data.tasks);

In dieser Zeile wird nur eine Funktion ausgeführt. Wir haben das Problem gefunden! ExampleApp.Collections.Tasks Ist undefined.

Schauen wir uns also an, wo das deklariert ist:

var Tasks = Backbone.Collection.extend({
    model: Task,
    url: '/tasks'
});

Wenn das alles der Code für diese Sammlung ist, dann ist die Ursache genau hier. Sie weisen den Konstruktor der globalen Variablen Tasks zu. Sie fügen es jedoch niemals dem Objekt ExampleApp.Collections Hinzu, von dem Sie später erwarten, dass es sich um ein Objekt handelt.

Ändern Sie das zu diesem, und ich wette, Sie würden gut sein.

ExampleApp.Collections.Tasks = Backbone.Collection.extend({
    model: Task,
    url: '/tasks'
});

Sehen Sie, wie wichtig die richtigen Namen und Zeilennummern sind, um dies herauszufinden? Betrachten Sie Fehler niemals als binär (es funktioniert oder nicht). Lesen Sie stattdessen den Fehler. In den meisten Fällen enthält die Fehlermeldung selbst die kritischen Hinweise, die Sie zum Auffinden des eigentlichen Problems benötigen.


Wenn Sie in Javascript eine Funktion ausführen, wird diese wie folgt ausgewertet:

expression.that('returns').aFunctionObject(); // js
execute -> expression.that('returns').aFunctionObject // what the JS engine does

Dieser Ausdruck kann komplex sein. Wenn Sie also undefined is not a function Sehen, bedeutet dies, dass der Ausdruck kein Funktionsobjekt zurückgegeben hat. Sie müssen also herausfinden, warum das, was Sie ausführen möchten, keine Funktion ist.

Und in diesem Fall, weil Sie etwas nicht dorthin gebracht haben, wo Sie dachten, dass Sie es getan haben.

80
Alex Wayne