Marionette js access to app from controller with requirejs

蓝咒 提交于 2020-01-05 04:56:21

问题


I want to get access to my main app instance from main controller to render new View. What i want to do is commented in controller/main.js code, as i understand this is circ dependency in require js, but i don't understand how to fix this

 file structure
       - controllers/main.js
       - models/
       - templates/
       - views/
       - app.js
       - main.js
       - router.js

main.js

require.config({...})
require(['app'], function(app) {
    app.initialize().start();
});

app.js

define(['jquery', 'underscore', 'backbone', 'marionette', 'router','controllers/main'],
function($, _, Backbone, Mn, Router, MainController) {

    let app = null;

    const App = Mn.Application.extend({
        region: '#app',
        initialize(options) {
            this.router = options.router;
        },
        onBeforeStart() {
            console.log('before start');
        },
        onStart() {
            Backbone.history.start();
        }
    });

    return {
        get instance() {
            return app;
        },
        initialize() {

            if (!app) {
                const controller = new MainController();
                const router = new Router({controller});
                app = new App({router});
            }
            return this;
        },
        start() {
            this.instance.start();
        },
    }
 });

router.js

define([
    'jquery',
    'underscore',
    'marionette',
], function($, _, Mn) {
    return Mn.AppRouter.extend({
        initialize(options) {
            this.controller = options.controller;
        },
        appRoutes: {
            '': 'index',
            'profile': 'profile',
            '*notFound': 'notFound'
        },
    });
});

controllers/main.js

define(['jquery', 'underscore', 'marionette', 'app'], function($, _, Mn, app) {
    return Mn.Object.extend({
        index() {
            console.log(app); // undefined
            console.log('index method invoked');
             /*
             i want to do like this
             app.showView(new SomeView());
             or this.triggerMethod('render', 'someView') and then listen for this event from app.js like this.router.controller.on('render', handler) and dynamic require somehow... 
             or what is best practice ? iam confused
             */
        },
        profile() {
            console.log('profile method invoked');
        },
        notFound() {
            console.log('notFound method invoked');
        }
    });
});

回答1:


You can asynchronously load the app inside index method of controller (wherever you need it) rather than adding it as a dependency of module

define(['jquery', 'underscore', 'backbone', 'marionette', 'router','controllers/main'],
  function($, _, Backbone, Mn, Router, MainController) {

    const App = Mn.Application.extend({
      region: '#app',
      initialize(options) {
        this.router = options.router;
      },
      onBeforeStart() {
        console.log('before start');
      },
      onStart() {
        Backbone.history.start();
      }
    });

    const controller = new MainController();
    const router = new Router({
      controller
    });

    return app = new App({
      router
    });
  });

define(['jquery', 'underscore', 'marionette'], function($, _, Mn) {
  return Mn.Object.extend({
    index() {
      require(['app'],function(app){
        console.log(app);
      });
    },
    profile() {
      console.log('profile method invoked');
    },
    notFound() {
      console.log('notFound method invoked');
    }
  });
});


来源:https://stackoverflow.com/questions/42270005/marionette-js-access-to-app-from-controller-with-requirejs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!