Trunk: Marionette.Application generates an error loading the Require.js module, "Error: module name" Application "has not yet been loaded for context: _"

I am trying to enable an instance of an application in order to use its event aggregator as shown here

I get an error when I include an instance in a view.

Disabling files in the Requirejs configuration file, from App.Bootloader.js:

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

from App.js:

 define(function (require){ //...requisite includes $, _, Backbone, Marionette ... var Layout = require('Layout'); var App = new Marionette.Application(); App.addRegions({ main: '#view_content' }); App.addInitializer(function (){ App.main.show(new Layout()); //... adding router etc ... Backbone.Marionette.TemplateCache.loadTemplate = function (template, callback){ callback.call(this, Handlebars.compile(template)); }; Backbone.history.start(); }); return App; }); 

From Layout.js:

 define(function(require){ var View = require('folder/folder/View'); //template contains #sub div var template = require('text!template.html'); return Marionette.Layout.extend({ template: template, regions: { sub: '#sub' }, initialize: function(){ //wait till template is rendered in dom _.defer(function(region){ region.sub.show(new View()); }, this) } }); }); 

In the folder /folder/folder/View.js:

 define(function (require){ //...requisite includes $, _, Backbone, Marionette ... var App = require('App'); return Marionette.ItemView.extend({}); }); 

Where I get the error "Error: module name" Application "has not yet been loaded for context: _"

Any ideas? Lemme knows if you need more information.

0
source share
4 answers

I am also looking for a good way to handle such situations using a puppet and require.js

I worked on a solution, but I don’t know if this is the best way, here are my thoughts:

  • the application has actions related to events, not knowing about the views
  • inside the view, we use triggers to attach actions to events
  • the combination of actions between the view and the application is done inside the view

This is a possible solution:

app.js

 define( [ 'underscore', 'jquery', 'backbone', 'marionette' , 'view'], function( _, $, Backbone, Marionette, View ) { var app = new Marionette.Application(); app.addRegions({ content: '#content'}) app.on( "initialize:after", function(){ console.log( 'after init', app) var view = new View(); app.content.show( view ); }); // this is the action that we would like to call from the view app.vent.on( 'viewClick', function(){ console.log( 'clicked on view' )}) return app; }); 

view.js

 define( [ 'underscore', 'jquery', 'backbone', 'marionette' ], function( _, $, Backbone, Marionette ) { var View = Marionette.ItemView.extend({ template: '#view', triggers: { 'click': 'clicked' }, initialize: function(){ // thisView will be referring to the view instance var thisView = this; // we require the app because we need access to the event aggregator require(['app'], function( app ){ // when our event is triggered on our view thisView.on( 'clicked', function(){ // we trigger an event on the application event aggregator app.vent.trigger( 'viewClick' ) }); }); } }) return View }); 

It is important to remember that require is asynchronous, so when we use it, it will not be executed immediately:

 require( ['some-module'], function( someModule ){ // do something, but only as soon as someModule is loaded }); 

we can prepare objects that point to an external context, for example:

 var thisName = this; require( ['some-module'], function( someModule ){ // access to external this using thisName }); 
+5
source

I think you have a circular dependency problem. App requires View and View requires App . Hmm ... But why does View require an App ? I can't figure it out from your code. After all, are you sure the View needs an App ? By the way, I think you were wrong. The first From /folder/folder/View.js should probably be From Layout.js .

+3
source

user1248256 is correct. I have the same problem. My application needs a controller, and my controller needs an application.

Moving to the controller (view for your code) as part of the parameters, I do not need to add it to the require.js definition.

 //data-main: define(function(require) { var $ = require("jquery"), _ = require("underscore"), App = require("app/App"), PublicRouter = require("routers/DesktopRouter"), PublicController = require("routers/publicController"); var options = { publicController : PublicController, publicRouter : PublicRouter } App.start(options); }); 

Now in the application I do not need to β€œrequire” a PublicController

 //App: define(['jquery', 'backbone', 'marionette', 'underscore'], function ($, Backbone, Marionette, _) { var App = new Marionette.Application(); ...snip... console.log("Creating Routers"); App.Routers = {}; // Connect controllers to its router via options // init router router/controller App.Routers.publicRouter = new options.publicRouter.Router({ controller: options.publicController }); }); 

Hope this helps.

Andrew

0
source

As a rule, I believe that using the EventAggregator application when using requireJS is not recommended, if not for any other reason, than it is very easy to complete a circular link.

Just define a separate EventAggregator module that App, View and Layout may require, and then add it depending on any module that needs it.

0
source

All Articles