2

我收到错误:NoMethodError:在控制器上找不到方法“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;
});

帮助路由器和控制器:

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

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

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 但它会引发错误

欢迎所有建议。

安德鲁

4

2 回答 2

2

看起来您的 RequireJS 导入有问题。HelpRouter变量映射到"routers/StartRouter"模块,并且所有后续模块都是一一对应的。

AMD 导入格式很容易导致这种类型的简单错误,这些错误可能需要很长时间才能调试,因为那是您从未想过要查看的地方。这就是为什么我更喜欢RequireJS 提供的简化 CommonJS 包装语法的原因:

define(function(require) {
  var HomeController  = require('routers/HomeController'),
      StartController = require('routers/StartController'),
      //etc...
});
于 2013-01-29T20:53:50.193 回答
0

对于那些刚刚收听的人来说,这里是 fencliff 提出的可行解决方案。

// Includes Desktop Specific JavaScript files here (or inside of your Desktop router)
define(function(require) {
  var App = require("app/App"),
        // Routers with its controller
        DesktopRouter       = require("routers/DesktopRouter"),
        HomeController      = require("routers/HomeController"),

        StartRouter         = require("routers/StartRouter"),
        StartController     = require("routers/StartController"),

        LoginRouter         = require("routers/LoginRouter"),
        LoginController     = require("routers/LoginController"),

        InspectorRouter     = require("routers/InspectorRouter"),
        InspectorController = require("routers/InspectorController"),

        PlayerRouter        = require("routers/PlayerRouter"),
        PlayerController    = require("routers/PlayerController"),

        HelpRouter          = require("routers/HelpRouter"),
        HelpController      = require("routers/HelpController");

  var options = {
      homeController:       HomeController,
      router:               DesktopRouter,

      startController:      StartController,
      startRouter:          StartRouter,

      loginController:      LoginController,
      loginRouter:          LoginRouter,

      inspectorController:  InspectorController,
      inspectorRouter:      InspectorRouter,

      playerController:     PlayerController,
      playerRouter:         PlayerRouter,

      helpController:       HelpController,
      helpRouter:           HelpRouter

  }
  App.start(options);
  return function() {};
});

我对返回一个空函数有点不确定,但这是我看到的唯一示例并且它有效。:-D

于 2013-01-30T16:17:28.533 回答