使用Marionette / Backbone并无法传递App对象以触发自定义事件。
具体来说,requirejs会抛出以下内容:"错误:模块名称" app"尚未加载上下文:_"。
修改:违规代码为" var App = require(' app');"在appController.js中。
根据我所阅读的内容,该消息指的是循环引用或尚未加载的脚本。我应该如何构建我的代码以避免这种情况?
注1:目前,我没有使用r.js.我确实有一个笨拙的构建过程,但没有机会设置r.js.只有在可以缓解我的问题的情况下才提及它。
注2:我没有使用Marionette的股票模块,因为我想学习requirejs。
提前致谢。
//config.js
require.config({
paths: {
jquery: '../jquery',
bootstrap: '../bootstrap',
underscore: '../lodash',
backbone: '../backbone',
'backbone.babysitter': '../backbone.babysitter',
'backbone.wreqr': '../backbone.wreqr',
marionette: '../backbone.marionette',
text: '../text'
},
enforceDefine: true,
shim: {
'bootstrap': {
deps: ['jquery'],
exports: '$'
},
}
});
define(
['app', 'jquery', 'underscore', 'backbone', 'marionette', 'bootstrap'],
function(App, $, _, Backbone, Marionette) {
App.start();
}
);
//app.js
define(function(require) {
var Marionette = require('marionette'),
// and AppRouter, AppController
var app = new Marionette.Application();
app.addInitializer(function() {
var router = new AppRouter({
controller: AppController
});
});
app.on('start', function() {
Backbone.history.start();
});
app.vent.on('custom:event', function(a) {
console.log('caught custom:event, received: ' + a);
});
return app;
});
// appRouter.js
define(function(require) {
var Marionette = require('marionette');
return Marionette.AppRouter.extend({
appRouter: {
'': 'main'
}
});
});
//appController.js
define(function(require) {
return {
main: function() {
var App = require('app');
App.vent.trigger('custom:event', ['test']);
}
}
});
更新
当然在发布此问题后,我找到了一个可能的解决方案。如果我将appController.js调整为以下内容,它可以正常工作。尽管如此,解决方案并不是正确的。我是否必须为每条路线复制它?
//appController.js (version 2)
define(function(require) {
return {
main: function() {
require(['app'], function(app) {
app.vent.trigger('custom:event', ['test']);
});
}
}
});
更新2
如果有人好奇,这就是我使用Backbone.Wreqr的方式(感谢@arisalexis)。仅显示从上面的代码更改的文件。
//app.js
define(function(require) {
var Marionette = require('marionette'),
Wreqr = require('backbone.wreqr'),
// and AppRouter, AppController
var app = new Marionette.Application();
app.addInitializer(function() {
var router = new AppRouter({
controller: AppController
});
});
app.on('start', function() {
Backbone.history.start();
});
// Get hook to global channel and listen for events!
var channel = Wreqr.radio.channel('global');
channel.vent.on('custom:event', function(a) {
console.log('caught custom:event, received: ' + a);
});
return app;
});
//appController.js
define(function(require) {
var Wreqr = require('backbone.wreqr');
var channel = Wreqr.radio.channel('global');
return {
main: function() {
channel.vent.trigger('custom:event', 'test');
}
}
});
注意,通常,路由器的控制器中不应包含任何逻辑。此问题中提供的代码是概念证明。
答案 0 :(得分:2)
我遇到了同样的问题并且无法解决,幸运的是因为它将在版本3中弃用。
来自文档:
要从应用程序中的其他对象访问此应用程序通道,建议您通过Wreqr API而不是Application实例本身来处理系统。
var globalCh = Backbone.Wreqr.radio.channel('global');
globalCh.vent;