Using the Backbone.js router to navigate through views modularized with require.js

前端 未结 8 883
别跟我提以往
别跟我提以往 2020-12-22 23:41

I am separating my views and router into separate files with require. I then have a main.js file that instantiates the router, and also renders my default view.

My r

相关标签:
8条回答
  • 2020-12-23 00:21

    I know this question is old, but I am wondering why haven't you use require.js in order to get the router:

    define(['./PathToRouter', ], function (router) {
        return Backbone.View.extend({
            template: Handlebars.compile($('#template').html()),
    
            events: {
                'click .edit': 'edit'
            },
    
            render: function () {
                //Create and insert the cover letter view
                $(this.el).html(this.template(this.model.toJSON()));
                $('#View').html(this.el);
    
                return this;
            },
    
            edit: function () {
                router.navigate('Edit/' + this.model.id, true);
            }
        });
    });
    
    0 讨论(0)
  • 2020-12-23 00:24

    For me, the solution with goTo function worked with a slight change

     Backbone.View.prototype.goTo = function (loc) {
          appRouter.navigate(loc, true);
        };
    
    0 讨论(0)
  • 2020-12-23 00:27

    You could do it the old fashioned way with window.location.hash :)

    window.location.hash = "Edit/1"
    

    Here's an alternate solution if you don't need explicit routes. When you app starts up create an object that extends Backbone Events

    window.EventDispatcher = _.extend({}, Backbone.Events);
    

    Then anywhere in you app you can listen for events

    EventDispatcher.bind("mymodel:edit", this.editHandler, this);
    

    And also from anywhere dispatch the event, data below are any params you want to send along for the ride

    EventDispatcher.trigger("mymodel:edit", data);
    
    0 讨论(0)
  • 2020-12-23 00:27

    I have a new solution for routing AMD modules.

    RequireJS Router https://github.com/erikringsmuth/requirejs-router

    This takes the approach of lazy loading AMD modules as you navigate to each page. With the Backbone router you need to require all of your views as dependencies up front. This loads all of your apps Javascript on the first page load. The RequireJS Router lazy loads modules as you navigate to each route.

    Example main.js used to run your app

    define([], function() {
      'use strict';
    
      // Configure require.js paths and shims
      require.config({
        paths: {
          'text': 'bower_components/requirejs-text/text',
          'router': 'bower_components/requirejs-router/router'
        }
      });
    
      // Load the router and your layout
      require(['router', 'js/layout/layoutView'], function(router, LayoutView) {
        var layoutView = new LayoutView();
        // The layout's render method should draw the header, footer, and an empty main-content section
        // then load the content section.
        // render: function() {
        //   this.$el.html(this.template({model: this.model}));
        //   router.loadCurrentRoute();
        // }
    
        // Configure the router
        router
          .registerRoutes({
            home: {path: '/', moduleId: 'home/homeView'},
            order: {path: '/order', moduleId: 'order/orderView'},
            notFound: {path: '*', moduleId: 'notFound/notFoundView'}
          })
          .on('statechange', function() {
            // Render the layout before loading the current route's module
            layoutView.render.call(layoutView);
          })
          .on('routeload', function(module, routeArguments) {
            // Attach the content view to the layoutView's main-content section
            layoutView.$('#main-content').replaceWith(new module(routeArguments).render().el);
          })
          .init({
            // We're manually calling loadCurrentRoute() from layoutView.render()
            loadCurrentRouteOnStateChange: false
          });
      );
    );
    
    0 讨论(0)
  • 2020-12-23 00:30

    As with pretty much any Backbone question, there are lots of ways to handle this. The way I approached it in my current project was to put everything in a global custom namespace, and use that to pass around the necessary references:

    var MyNamespace = {};
    
    MyNamespace.init = function() {
        MyNamespace.appView = new MyAppView();
        MyNamespace.router = new MyRouter();
        // etc
    }
    

    Views could then refer to MyNamespace.router as necessary. But it looks like this won't work/isn't encouraged with require.js, so here are some other options:

    • Don't ever call the router explicitly - instead, change a global state object that the router listens to. This is actually how I've done things in my current project - see this response for more details.

    • Attach the router to your top-level view, often called AppView, make that globally accessible, and use AppView.router.navigate().

    • Make another module that provides a navigate utility function that calls Backbone.history.navigate() internally. This isn't much different from what you're doing, but it would make it slightly more modular and keep you from using the global reference all the time. This also allows you to change the internal implementation.

    0 讨论(0)
  • 2020-12-23 00:39

    for me i added an object to the main application like so;

    define(['jquery','underscore','backbone','views/personView','views/peopleView','views/textView'],function($,_,backbone,PersonView,PeopleView,TitleView){
    
        var Router = Backbone.Router.extend({
               routes:{
                   '':'home',
                   'edit/:id':'editPerson',
                   'new':'editPerson',
                   'delete/:id':'deletePerson'
                   }
                })
    
                  var initialize = function(){
    
                     var router  = new Router();
    
                     window.app = {
                         router:router
                         }
    
            router.on('route:home',function(){
    
    
        })
    
                //enable routing using '#'[hashtag] navigation
            Backbone.history.start();
    
                };
    
                return {
                initialize:initialize
                };
    
    });
    

    and inside your view, you can say windows.app.router.navigate({'',trigger:true}) . Don't know if global scoping is good practice in this case, but it worked for me.

    0 讨论(0)
提交回复
热议问题