2012-06-15 5 views
0

Я пытаюсь включить экземпляр приложения для использования его агрегатора событий как показано hereМагистральная магистраль: Marionette.Application, вызывающая ошибку загрузки модуля Require.js, «Ошибка: имя модуля« Приложение »еще не загружено для контекста: _«

Я получаю сообщение об ошибке, когда включаю экземпляр в виде.

Ногами вещи в конфигурационном файле Requirejs, из App.Bootloader.js:

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

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

От 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) 
     } 

    }); 

}); 

От /folder/folder/View.js:

define(function (require){ 

     //...requisite includes $, _, Backbone, Marionette ... 

    var App = require('App'); 
    return Marionette.ItemView.extend({}); 
}); 

Где я получаю сообщение об ошибке «" Ошибка: Имя модуля „App“ еще не был загружен в контексте: _»

Любые идеи? Lemme знает, нужна ли вам дополнительная информация.

ответ

3

У вас возникли проблемы с circular dependencies. AppView и ViewApp. Хм ... Но зачем ViewApp? Я не могу понять это из вашего кода. В конце концов, вы уверены, что View нуждается в App? Кстати, я думаю, ты ошибся. Первый From /folder/folder/View.js, вероятно, должен быть From Layout.js.

+0

Да, вы правы в отношении опечатки, это исправлено. Теперь я не вижу круговой зависимости: App требуется Макет, Макет отображает View, View calls App, потому что в Marionette приложение имеет бесценный Event Aggregator (т.е. App.vent.trigger или App.vent.bind), используемый для просмотра перекрестных просмотров aka pub sub. –

+0

Временный взлом заключался в том, чтобы экспортировать приложение в window.App для других, чтобы получить к нему доступ, но это не должно быть необходимо и нарушает философию содержащихся модулей. –

+1

Хорошо, вы можете использовать [специальный модуль 'export'] [1]. Например: http://stackoverflow.com/questions/4881059/how-to-handle-circular-dependencies-with-requiesjs-amd 1: https://github.com/jrburke/requirejs/wiki/Differences-between -the-simplified-CommonJS-wrapper-and-standard-AMD-define # wiki-magic – theotheo

5

Я также ищу хороший способ справиться с такого рода ситуациями, используя марионетку и require.js

Я работал над решением, но я не знаю, если это лучший способ, здесь мои мысли:

  • заявка действие, присоединенное к событиям, не зная о взглядах
  • внутри вида мы используем триггера приложить действия к событиям
  • связи действий между видом и приложением сделал внутри вида

Это возможное решение:

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

, важно помнить, что требуется асинхронный, так когда мы его используем, он не будет выполнен немедленно:

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

мы можем подготовить объекты Wich точку внешнего контекста, например:

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

Это решение было упомянуто в документах Marionette [здесь] (https://github.com/marionettejs/backbone.marionette/wiki/Using -марионет-с-requirejs), но без примера. Этот пример работал для меня. Благодаря! –

+0

Это похоже на то, что мне тоже нужно - к сожалению, я нашел весь этот процесс достаточно раздражающим, чтобы придерживаться конвейера активов ... haha – MBHNYC

0

user1248256 правильно.У меня такая же проблема. Моему приложению нужен контроллер, а моему контроллеру необходимо приложение.

Передача в контроллер (представление для вашего кода) как части параметров. Мне не нужно добавлять его в определение require.js.

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

Сейчас в App я не должен "требовать" в 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's router/controller 
     App.Routers.publicRouter = new options.publicRouter.Router({ 
      controller: options.publicController 
     }); 
    }); 

Надежда, что помогает.

Эндрю

0

Я вообще считаю, что это плохая практика, чтобы использовать EventAggregator в приложениях при использовании requireJS, если ни по какой другой причине, чем это на самом деле легко заводиться с круговой ссылкой.

Просто определите отдельный модуль EventAggregator, который может потребоваться App, View и Layout, а затем добавьте его в зависимости от любого модуля, который в нем нуждается.