1

クリーンなコードベースを維持するために、モジュール間でメッセージを送信するためにhttps://github.com/addyosmani/backbone-aura/のモジュラーおよびファサード/メディエーター pub/sub パターンを組み合わせたバックボーンでアプリケーションを構築しています。

aura のRouterアプリの例全体を調べてみると、モジュール自体の一部であるルーターの理想的な使用法を説明している readme ファイルしか見つかりませんでした。ウィジェットをレンダリングするために必要なテンプレート。」

set-routeそこで、メッセージを受け取ってルートを設定するルーターモジュールや、メッセージをリッスンするモジュールなど、スケーラブルなルーティングシステム (モジュールが独自のサブルートを指定できるというスケーラブルな意味) を実装するためのソリューションをいくつか試しましたroute。モジュールごとにサブルーターも使用しました。この問題は、最初のページの読み込み時に、メッセージングの「非同期」の性質のために、グローバル ルーターが URL を解析するまでにルートとそのコールバックが定義されていない可能性があるようです。ルーター モジュールを起動する前に、すべてのメッセージをキューに入れる必要があると想像できます。

何かきれいなものを実装したいのですが、それは理にかなっています。また、最初にすべてのウィジェットのすべてのルートを解析し、次にルーターをインスタンス化する可能性も考えていました。これにより、ルーター モジュールが特殊なケースになるため、モジュールの一部であってはなりません。

Router はメッセージを使用するモジュールである必要がありますか、それとも拡張機能である必要がありますか、またはモジュールがアクセスできるグローバルなアーキテクチャの高次の部分である必要がありますか?

私はこれが負荷の高い質問であることを知っています。事前に助けてくれてありがとう!

4

1 に答える 1

1

この問題については多くの議論がありましたが、その多くは、ルーターが正式にコントローラーと呼ばれていることについての混乱から生じたと思います。去年の終わりにBackboneを使い始めた頃には、すでに変更が加えられていましたが、多くの人がすでにコントローラーであるルーターを中心にアプリケーションを構築していたと思います。私はそれに同意しませんでした。私にとって、Backboneが作成されるずっと前にBackboneと同様の独自のMVCエンジンを構築した経験に依存して、ルーターは単なる履歴マネージャーコンポーネントでした。

したがって、ルーターの実装に最適な方法を決定する際の特定の問題に対処するには、いくつかの点を考慮してください。

  1. まず第一に、ルーターはアプリケーションの必須コンポーネントではありません。ルーターがなくても、アプリのさまざまなページや画面に移動できます。
  2. ルーターは、その主な機能が履歴の​​管理であるという点でコントローラーではありません。アプリケーションのビジネスロジックをルーターに埋め込むことはできますが、それがルーターの実際の機能の水面を濁していることにいつも気づきました。
  3. ルーターをアプリケーションのコンポーネントにすることで、関心の分離を改善し、はるかに効果的なパブ/サブタイプの配置を実現できます。

以下は、メディエーター、pub / subパターンに従う、アプリで使用するルーターモジュールのコードです。

/**
 * The idea behind this component is simply to relegate Backbone.Router to
 * doing what it does best: History Management. All it is responsible for
 * is two things:
 *
 * 1. Update the URL if router.navigate is invoked
 * 2. Trigger a routeChanged event if the URL was updated either by a bookmark or
 *    typed in by a user.
 */
define(function () {
    return Backbone.Router.extend({
        initialize : function (map) {
            this._reversedMap = this.reverseModuleMap(map);
        },
        routes:{
            '*actions':'notify'
        },
        notify:function (actions) {
            var args = arguments;
            this.trigger("routeChanged", {command:actions});
        },
        /**
         * Override Backbone.Router.navigate. Default is to pass a router fragment, but for
         * our uses, we'll translate the "route" into a module mapping so that the controller
         * will know which module to display.
         * @param param
         * @param options
         */
        navigate:function (param, options) {
            //console.log('navigate', param);
            if(!param.suppressNavigate && param.actionCommand)  {
                Backbone.Router.prototype.navigate.call(this, this._reversedMap[param.actionCommand]);
            } else if(!param.actionCommand) {
                Backbone.Router.prototype.navigate.call(this, param, options);
            }
        },
        /**
         * this function simply reverses the key and value of the "map"
          * @param map
         */
        reverseModuleMap:function (map) {
            var newMap = {};
            _.each(map, function (value, key) {
                newMap[value] = key;
            });
            // reversed key and value
            return newMap;
        }
    });
});

次に、コンポーネントをインスタンス化するときに、マップを渡して、コントローラーがナビゲートするモジュールを認識できるようにします。

this._router = new Router({
    _default: 'moduleA',
    sites : 'moduleA',
    apps : 'moduleB'
});
this._router.on('routeChanged', this.handleRouteChange, this);

これで私が見つけた最も重要なことは、コードを素晴らしくシンプルに保ち、コントローラーのビジネスロジックに集中できることです。

于 2012-08-01T19:22:26.890 に答える