backbone.js - Marionette.js NoMethodError : Method 'xxx' was not found on the controller but it is there

标签 backbone.js marionette

我收到错误:NoMethodError:在 Controller 上找不到方法“go_start”

函数 go_start 在我的项目中只出现在两个地方(我搜索过): StartRouter.js

define(['marionette'], function(Marionette) {
  'use strict';

  var StartRouter = {};

  StartRouter.Router = Marionette.AppRouter.extend({
    appRoutes: {
        "start": "go_start"
    }
  });

  return StartRouter;
});

和 StartController.js

define(['underscore', 'marionette', 'app/vent',
    'text!templates/StartLayout.html',     'views/InspectorStartView','views/InspectorStartView'],
function(_, Marionette, vent, layout, InspectorStartView, PlayerStartView) {
'use strict';

// public module API
var Controller = {};

// private
var Layout = Marionette.Layout.extend({
    template: _.template(layout),

    regions: {
        inspector: "#inspector_choice",
        player: "#player_choice"
    }
});

// private
var _initializeLayout = function() {
    console.log('initializeLayout...');
    Controller.layout = new Layout();
    Controller.layout.on("show", function() {
        vent.trigger("layout:rendered");
    });
    vent.trigger('app:show', Controller.layout);
};

// controller attach a sub view/ search View
vent.on("layout:rendered", function() {
    console.log('layout:rendered =>StartController');

    // render views for the existing HTML in the template, and attach it to the layout (i.e. don't double render)
    var inspectorStartView = new InspectorStartView();
    Controller.layout.inspector.attachView(inspectorStartView);

    var playerStartView = new PlayerStartView();
    Controller.layout.player.attachView(playerStartView);
});

    // controller show inspector in the layout / subview
    vent.on('show:inspector', function(inspectorStartView) {
        // console.log('show books event');
        Controller.layout.inspector.show(inspectorStartView);
    });

    // controller show inspector in the layout / subview
    vent.on('show:player', function(playerStartView) {
        // console.log('show books event');
        Controller.layout.inspector.show(playerStartView);
    });


// public API
Controller.go_start = function(term) {   **//<-- function go_start**
    _initializeLayout();
    //vent.trigger("search:term", term);
};

return Controller;

真正奇怪的部分是 Crome 显示 App.js 第 77 行发生的错误,即:

app.addInitializer(function(options) {
    // configure for loading templates stored externally...
    Backbone.Marionette.TemplateCache.prototype.loadTemplate = function(templateId) {
        // Marionette expects "templateId" to be the ID of a DOM element.
        // But with RequireJS, templateId is actually the full text of the template.
        var template = templateId;

        // Make sure we have a template before trying to compile it
        if (!template || template.length === 0) {
            var msg = "Could not find template: '" + templateId + "'";
            var err = new Error(msg);
            err.name = "NoTemplateError";
            throw err;
        }

        return template;
    };

    // Connect controllers to its router via options
    // init router's router/controller
    new options.router.Router({
        controller: options.homeController
    });

    // init loginRouter's router/controller
    new options.loginRouter.Router({
        controller: options.loginController
    });
    // init helpRouter's router/controller
    new options.helpRouter.Router({
        controller: options.helpController  //<-- Line 77
    });
    // init startRouter's router/controller
    new options.startRouter.Router({
        controller: options.startController
    });
    // init inspectorRouter's router/controller
    new options.inspectorController.Router({
        controller: options.inspectorController
    });
    // init playerRouter's router/controller
    new options.playerRouter.Router({
        controller: options.playerController
    });
});
// export the app
return app;
});

帮助路由器和 Controller :

// HelpRouter.js
define(['marionette'], function(Marionette) {
'use strict';

var HelpRouter = {};

HelpRouter.Router = Marionette.AppRouter.extend({
    appRoutes: {
        "help": "go_help"
    }
});

return HelpRouter;
});

<!-- routes/HelpController.js -->
define(['underscore', 'marionette', 'app/vent',     'text!templates/HelpLayout.html'],
function (_, Marionette, vent, layout) {
    'use strict';

    // public module API
    var Controller = {};

    // private
    var Layout = Marionette.Layout.extend({
        template: _.template(layout),

        regions: {
            faq: "#"
        }
    });

// private

var _initializeLayout = function () {
console.log('initializeLayout...');
Controller.layout = new Layout();
Controller.layout.on("show", function () {
    vent.trigger("layout:rendered");
});
vent.trigger('app:show', Controller.layout);
};


// public API

Controller.go_help = function () {
     _initializeLayout();
};

return Controller;
});

有人看到我做错了什么吗?
这是我认为不应该发生的事情:

// Includes Desktop Specific JavaScript files here (or inside of your Desktop router)
require(["app/App",
    "routers/HomeController",       "routers/StartController",  "routers/LoginController",
    "routers/InspectorController",  "routers/PlayerController", "routers/HelpController",
    "routers/DesktopRouter",        "routers/LoginRouter",      "routers/StartRouter",
    "routers/InspectorController",  "routers/PlayerController", "routers/HelpRouter" ],
function(App,
       HomeController, StartController, LoginController, InspectorController, PlayerController, HelpController,
       DesktopRouter, LoginRouter, HelpRouter, StartRouter, InspectorRouter, PlayerRouter) {

  var options = {
      homeController:       HomeController,
      startController:      StartController,
      loginController:      LoginController,
      helpController:       HelpController,

      inspectorController:  InspectorController,
      playerController:     PlayerController,

      router:               DesktopRouter,
      startRouter:          StartRouter,
      loginRouter:          LoginRouter,
      helpRouter:           HelpRouter,

      inspectorRouter:      InspectorRouter,
      playerRouter:         PlayerRouter

  };

  App.start(options);
});

所以我需要所有路由器和 Controller ,但是当我在调试器中运行该代码时,我有一些未定义的项目:

options: Object
helpController: Object
helpRouter: Object
homeController: Object
go_home: function () {
__proto__: Object
inspectorController: undefined
inspectorRouter: undefined
loginController: Object
loginRouter: Object
playerController: undefined
playerRouter: Object
router: Object
Router: function (){ parent.apply(this, arguments); }
__proto__: Object
startController: Object
go_start: function (term) {
__proto__: Object
startRouter: undefined
__proto__: Object
HomeController: Object
StartController: Object
StartRouter: undefined
DesktopRouter: Object
InspectorController: undefined

为什么有些未定义? StartRouter和StartController具有go_start函数。 HelpRouter/Controller 没有也不应该有 go_start,但它抛出错误

欢迎所有建议。

安德鲁

最佳答案

您的 RequireJS 导入似乎出现故障。 HelpRouter 变量映射到 "routers/StartRouter" 模块,所有后续模块都相差一。

AMD 导入格式很容易导致这种类型的简单错误,这些错误可能需要很长时间才能调试,因为不知何故,这是您从未想过要查看的地方。这就是为什么我更喜欢 simplified CommonJS wrapper syntax由RequireJS提供:

define(function(require) {
  var HomeController  = require('routers/HomeController'),
      StartController = require('routers/StartController'),
      //etc...
});

关于backbone.js - Marionette.js NoMethodError : Method 'xxx' was not found on the controller but it is there,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14591996/

相关文章:

javascript - 在主干集合中获取数据并显示 View 的有效方法?

javascript - 检测 body 与 Backbone 滚动( Marionette )

javascript - 方法未在 backbone.js + coffeescript 上定义

javascript - 每次收到 XHR 请求时,如何使用 JQuery AjaxSetup 将 "csrf"设置为参数?

javascript - 在 jQuery slider 移动时获取其值

backbone.js - Marionette JS : Using a collection with two or more views for different layouts

javascript - Marionette.js 模板打印不完整

javascript - 使用 Marionette.CompositeView 进行单元测试

backbone.js - CollectionView 内的 Marionette 多个 View

backbone.js - 将 Backbone 应用程序作为独立的 JS 应用程序运行 - 路由不起作用