【问题标题】:Backbone.Marionette Change Region when Route changesBackbone.Marionette 路由改变时改变区域
【发布时间】:2013-02-20 12:50:43
【问题描述】:

我的应用有一个主要区域,有时在主要区域中会有一些子区域,这些子区域应该可以通过 URL 访问。主要区域内容由应用程序路由器的功能更改,因为他知道主要区域。但是子视图中的临时区域呢?

例如,url /docs 将显示文档链接列表,/doc/:id 应在列表旁边显示文档的内容。那么/doc/:id 怎么能在有人点击列表时呈现内容,而当有人在新标签页中打开 url 时同时呈现列表和内容。

据我所知,有两个选项可以为每个区域配备一个路由器,或者区域管理器触发带有应该更改的路由和区域的事件。有关解决此问题的最佳方法的任何提示。

【问题讨论】:

    标签: backbone.js marionette


    【解决方案1】:

    好的,我想出了一个适用于每个区域的路由器解决方案。路由器可以通过路线图和视图轻松配置。当一条路线匹配最初通过的区域时,将显示一个新的视图实例。

    Here 是路由器的高级版本,路由参数将传入视图。

    更新

    上述解决方案仅适用于每条路线仅注册一次。如果您第二次注册相同的路由,第一次的回调将被覆盖。所以我想出了一个解决方案,区域控制器不直接在路由器上注册路由,而是在全局事件总线(Marionette.Application.vent)上监听route:change事件,然后路由器在此触发route:change事件事件总线。

    路由器控制器:

    // The problem with backbone router is that it can only register one function per route
    // to overcome this problem every module can register routes on the RouterController
    // the router will just trigger an event on the `app.vent` event bus when ever a registered routes match
    define(function() {
    
      function RouterController(vent) {
        this.vent = vent;
        this.router = new Backbone.Router();
      }
    
      RouterController.prototype = _.extend({
          //just pass the route that change you wanna listen to
          addRoutes: function(routes) {
            _.each(routes, function(route) {
              this.router.route(
                route,
                _.uniqueId('e'),
                //create a closure of vent.trigger, so when ever the route match it simply trigger an event passing the route
    //            _.partial(_.bind(this.vent.trigger, this.vent), 'route:change', route)
                _.bind(function() {
                  this.vent.trigger.apply(this.vent, ['route:change', route].concat(_.toArray(arguments)));
                }, this)
              );
            }, this);
    
          }
        },
        Backbone.Events);
    
      return RouterController;
    });
    

    区域路由器:

    define(['common/App'], function(app) {
    
        function RegionRouter(region, routerSettings) {
          app.router.addRoutes(_.keys(routerSettings));
    
          this.listenTo(app.vent, 'route:change', function() {
            var route = arguments[0];
            var View = routerSettings[route];
    
            if (!View) {
              return;
            }
    
            var params;
    
            if (arguments.length > 1) {
              params = computeParams(arguments, route);
            }
            region.show(new View(params));
          });
        }
    
        RegionRouter.prototype = _.extend(
          {
            onClose: function() {
              this.stopListening(app.vent);
            }
          }, Backbone.Events
        );
    
        function computeParams(args, route) {
          args = Array.prototype.slice.call(args, 1);
    
          //map the route params to the name in route so /someroute/:somevalue will become {somevalue: passedArgs}
          //this object will be passed under the parameter key of the options
          var params = {};
          var regEx = /(?::)(\w+)/g;
          var match = regEx.exec(route);
          var count = 0;
          while (match) {
            params[match[1]] = args[count++];
            match = regEx.exec(route);
          }
    
          return {params: params};
        }
    
        return RegionRouter;
      }
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      • 2018-11-18
      • 1970-01-01
      相关资源
      最近更新 更多