web-dev-qa-db-fra.com

"Uncaught TypeError: undefined n'est pas une fonction" - Débutant Backbone.js Application

Je suis en train de mettre en place une application assez simple avec colonne vertébrale, et je reçois une erreur.

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

C’est là que l’erreur apparaît dans Chrome Inspecteur (fichier init - exemple_app.js):

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

Voici mon fichier index.haml de tâches

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

Et voici la preuve que j'appelle tous les fichiers (je pense):

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

Toutes les idées seraient géniales. Merci!

38
jake

Uncaught TypeError: undefined n'est pas une fonction example_app.js: 7

Ce message d'erreur raconte toute l'histoire. Sur cette ligne, vous essayez d'exécuter une fonction. Cependant, ce qui est exécuté n'est pas une fonction! Au lieu de cela, c'est undefined.

Alors que se passe-t-il example_app.js ligne 7? Ressemble à ça:

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

Une seule fonction est exécutée sur cette ligne. Nous avons trouvé le problème! ExampleApp.Collections.Tasks est undefined.

Voyons donc où cela est déclaré:

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

Si c'est tout le code pour cette collection, la cause principale est ici. Vous affectez le constructeur à une variable globale appelée Tasks. Mais vous ne l'ajoutez jamais à la ExampleApp.Collections objet, un endroit que vous attendez plus tard.

Changer cela en cela, et je parie que vous seriez bon.

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

Vous voyez à quel point les noms propres et les numéros de ligne sont importants pour comprendre cela? Ne considérez jamais les erreurs comme binaires (cela fonctionne ou non). Au lieu de lire l'erreur, dans la plupart des cas, le message d'erreur lui-même vous donne les indices critiques à suivre pour trouver le problème réel.


En Javascript, lorsque vous exécutez une fonction, elle est évaluée comme suit:

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

Cette expression peut être complexe. Alors quand tu vois undefined is not a function _ cela signifie que l'expression n'a pas renvoyé d'objet fonction. Vous devez donc comprendre pourquoi ce que vous essayez d'exécuter n'est pas une fonction.

Et dans ce cas, c'est parce que vous n'avez pas mis quelque chose où vous pensiez l'avoir fait.

80
Alex Wayne