2012-12-14 5 views
2

J'essaie de me familiariser avec Backbone et exige JS en utilisant marionette pour certaines de ses excellentes caractéristiques. Cependant je trouve quelques problèmes avec l'application étant disponible aux vues:Backbone JS, Marionette et Require JS

main.js

require(['application'], function(app){ 
app.start(); 
}); 

application.js

define([ 
'marionette', 
'router' 
], function(marionette, Router){ 

"use strict"; 

var app = new marionette.Application(); 

app.addRegions({ 
    header : 'header', 
    main : '#main' 
}); 

app.addInitializer(function(){ 
    this.router = new Router(); 
}); 

return app; 

}); 

dashboard.js

define([ 
'application', 
'underscore', 
'backbone', 
], function(app, _, Backbone) { 
var DashboardView = Backbone.View.extend({ 

initialize: function() { 
    console.log(app); 
    $('a').click(function(e){ 
     e.preventDefault(); 
     app.router.navigate("claims", { 
      trigger: true 
     }); 
    }); 
}, 

}); 
return DashboardView; 
}); 

I suis recevoir indéfini dans le journal de la console? L'application doit-elle utiliser les modules requirejs à la place?

EDIT: Mise à jour avec besoin

require.config({ 

paths: { 
    'jquery'  : '../vendors/jquery-1.8.2', 
    'underscore' : '../vendors/underscore', 
    'text'   : '../vendors/text', 
    'json2'   : '../vendors/json2', 
    'backbone'  : '../vendors/backbone', 
    'marionette' : '../vendors/plugins/backbone.marionette', 
    'paginator'  : '../vendors/plugins/backbone.paginator', 
    'relational' : '../vendors/plugins/backbone.relational', 
    'moment'  : '../vendors/moment', 
    'bootstrap'  : '../vendors/bootstrap', 
    'datepicker' : '../vendors/plugins/bootstrap.datepicker', 
    'templates'  : 'templates/' 
}, 

shim: { 

    backbone: { 
     deps: ['underscore', 'jquery'], 
     exports: 'Backbone' 
    }, 
    marionette : { 
     exports : 'Backbone.Marionette', 
     deps : ['backbone'] 
    }, 
    paginator: { 
     deps: [ 
     'backbone', 
     'underscore', 
     'jquery' 
     ], 
     exports: 'Backbone.Paginator' 
    }, 
    relational: ['backbone'], 
    underscore: { 
     'exports': '_' 
    }, 
    bootstrap: { 
     deps: ['jquery'], 
     exports: "bootstrap" 
    }, 
    datepicker: { 
     deps: ['jquery','bootstrap'], 
     exports: "datepicker" 
    }, 
    moment: { 
     exports: 'moment' 
    } 
} 

}); 

require(['application'], function(app){ 
    app.start(); 
}); 

routeur

define([ 
    'views/claims/PaginatedList', 
    'views/dashboard/Dashboard' 
    ], function(PaginatedClaimListView, DashboardView){ 

var Router = Backbone.Router.extend({ 

    routes: { 

     "": "index", 
     "claims": "claims" 

    }, 

    initialize: function(){ 
     Backbone.history.start({ 
      pushState: true, 
      root: '/app_dev.php/hera' 
     }); 
    }, 

    index: function(){ 
     var dashboard = new DashboardView(); 
    }, 

    claims: function(){ 
     var claimListView = new PaginatedClaimListView(); 
    } 

}); 

return Router; 

}); 
+0

Comment avez-vous configuré require.js? Pouvez-vous signaler vos configurations de shim et de chemins? – Ingro

+0

@Ingro J'ai ajouté cela dans ma question originale maintenant, merci. –

+0

Eh bien, je ne vois rien d'étrange, j'utilise une configuration similaire (je ne fais pas de proxy marionette et j'utilise la syntaxe complète quand j'en ai besoin, comme 'new Backbone.Marionette.Application()') et tout fonctionne bien.Comment avez-vous appelé dashboard.js? C'est l'application définie dans votre fonction principale? Qu'y a-t-il dans 'vent'? – Ingro

Répondre

2

Je pense que je l'ai compris, même si je ne suis pas sûr à 100% pourquoi.

Le problème réside dans votre définition Router. Mettre vos vues avec une référence à Application fait que le routeur commence avant que app.start() soit appelé dans main.js. En fait, si vous mettez un console.log(app) dans votre main.js, vous remarquerez qu'il est appelé après celui de dashboard.js.

Alors, voici comment je l'ai résolu, il:

define(['backbone'], function(Backbone){ 

var Router = Backbone.Router.extend({ 

    routes: { 
     "": "index", 
     "claims": "claims" 
    }, 

    initialize: function(){ 
     Backbone.history.start({ 
      pushState: true, 
      root: '/app_dev.php/hera' 
     }); 
    }, 

    index: function(){ 
     require(['views/dashboard/Dashboard'],function(DashboardView){ 
      var dashboard = new DashboardView(); 
     }); 
    }, 

    claims: function(){ 
     require(['views/claims/PaginatedList'],function(PaginatedClaimListView){ 
      var claimListView = new PaginatedClaimListView(); 
     }); 
    } 

}); 

return Router; 

}); 

Je ne sais pas s'il y a une meilleure solution qui garde vos vues définies dans votre routeur, de toute façon cela fonctionne et feront de votre routeur plus léger, en particulier Si votre opinion a grandi en nombre ...

+1

Merci pour cela, j'ai fait les changements et tout fonctionne très bien maintenant. Vous avez raison d'être plus léger aussi, je n'ai pas pensé à eux étant nécessaire même si elles n'étaient pas nécessaires. Je pense que je comprends pourquoi c'est arrivé, merci pour toute votre aide! –

0

J'ai trouvé que généralement chaque fois que j'ai modules Require.js mis à undefined quand ils ne devraient pas être, il est à cause de une dépendance circulaire. Par exemple, disons que "vent" dépend du "tableau de bord"; vous auriez: vent besoins dashboard besoins application besoins vent ...

Lorsque cela se produit la réponse de require est essentiellement juste pour choisir un seul des fichiers et le faire fonctionner, mais l'un des autres fichiers impliqués dans la dépendance circulaire entrer en tant que undefined.

Vous pouvez tester cette théorie en supprimant les importations pour voir si cela corrige votre undefined. Alternativement, les gens de Require ont un outil que vous pouvez télécharger appelé xrayquire qui aide à trouver des dépendances circulaires.

+0

Merci pour la réponse, j'ai tout enlevé de l'application mais je reçois toujours undefined donc à la case départ. –

0

Avez-vous besoin d'accéder au routeur via app.router? Ne pouvez-vous pas simplement avoir un tableau de bord nécessitant un routeur et y accéder directement? Tant que l'application a déjà été exécutée (ce qui devrait être le cas, à ce stade), vous n'avez pas besoin d'y accéder via l'application. Je pense que votre problème est définitivement une dépendance circulaire compliquée.