3

私のアプリにはメイン リージョンがあり、URL でアクセスできるメイン リージョンにサブ リージョンが存在する場合があります。メイン リージョンのコンテンツは、アプリ ルーターがメイン リージョンを認識している関数によって変更されます。しかし、サブビューの一時的な領域はどうですか?

たとえば、URL/docsはドキュメントへのリンクのリストを表示し、リストの/doc/:id横にドキュメントのコンテンツを表示する必要があります。/doc/:idたとえば、リストをクリックしたときにコンテンツをレンダリングし、新しいタブでURLを開いたときにリストとコンテンツの両方をレンダリングするにはどうすればよいでしょうか。

私が見る限り、すべてのリージョンにルーターを持つ 2 つのオプションがあります。または、リージョン マネージャーがルートとリージョンを変更する必要があるイベントを発生させます。この問題を解決する最善の方法のヒント。

4

1 に答える 1

4

わかりました。リージョンソリューションごとに1つのルーターを考え出しました。ルーターは、ルートとビューのマップによって簡単に構成できます。ルートが最初に渡されたリージョンと一致するたびに、ビューの新しいインスタンスが表示されます。

これは、ルートパラメータがビューに渡されるルーターの高度なバージョンです。

アップデート

上記の解決策は、すべてのルートが1回だけ登録されている場合にのみ機能します。同じルートを2回登録すると、最初のルートのコールバックが上書きされます。そこで、リージョンコントローラーがルーターに直接ルートを登録するのではなくroute:change、グローバルイベントバス(Marionette.Application.vent)でイベントをリッスンし、ルーターがroute:changeこのイベントバスでイベントをトリガーするソリューションを考え出しました。

RouterController:

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

RegionRouter:

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;
  }
);
于 2013-02-20T13:36:03.820 に答える