17

私は Backbone アプリケーションを開発してしばらく経ちましたが、Require.js で Backbone を使用する方法を学び始めたところです。

リファクタリング中のバックボーン アプリでは、次のような名前空間を定義しましたApp.model.repo。このモデルは、さまざまなビューで何度も使用されています。たとえば、いくつかのコレクションで同じことを行いApp.collection.filesます。これらのモデルとコレクションは、最初のインデックス ファイル リクエストでブートストラップされます。

this exampleを見つけました。これは、ブートストラップされたデータを取得するための優れた方法のように見えます。ただし、これらのモデルとコレクションをビュー間で再利用/共有するための最良の方法に苦労しています。

考えられる解決策は 3 つ考えられます。どちらが最適で、その理由は? または、私が完全に見逃している別の解決策はありますか?

解決策 1

これらの共通モジュールとコレクションをインデックスで定義し (それらがブートストラップされる場合)、それらをオプションとして各バックボーン ビューに渡します (のinitialize)。

define(['jquery', 'underscore', 'backbone', 'handlebars', 'text!templates/NavBar.html'], 
    function($, _, Backbone, Handlebars, template){     
        return Backbone.View.extend({
            template: Handlebars.compile(template),
            initialize: function(options){
                this.repoModel = options.repoModel; // common model passed in
            }
        });
    }
);

これらは分離に関してはきれいに見えますが、たくさんのものがあちこちに渡されて、ファンキーな速さになる可能性があります.

解決策 2

モジュールを定義し、globalsよく使用されるモデルとコレクションをそれに追加します。

// models/Repo.js
define(['backbone'],
    function(Backbone){
        return Backbone.Model.extend({
            idAttribute: 'repo_id'
        });
    }
);

// globals.js (within index.php, for bootstrapping data)
define(['underscore', 'models/Repo'], 
    function(_, RepoModel){     
        var globals = {};
        
        globals.repoModel = new Repo(<?php echo json_encode($repo); ?>);
        
        return globals
    }
);

define(['jquery', 'underscore', 'backbone', 'handlebars', 'text!templates/NavBar.html', 'globals'], 
    function($, _, Backbone, Handlebars, template, globals){
        var repoModel = globals.repoModel; // repoModel from globals
        
        return Backbone.View.extend({
            template: Handlebars.compile(template),
            initialize: function(options){

            }
        });
    }
);

この解決策は、AMD のすべてのポイントを無効にしますか?

解決策 3

一部のモデルとコレクションがコンストラクターではなくインスタンスを返すようにします (効果的にそれらをシングルトンにします)。

// models/repo.js
define(['backbone'],
    function(Backbone){
        // return instance
        return new Backbone.Model.extend({
            idAttribute: 'repo_id'
        });
    }
);

// Included in index.php for bootstrapping data
require(['jquery', 'backbone', 'models/repo', 'routers/Application'],
    function($, Backbone, repoModel, ApplicationRouter){
        repoModel.set(<?php echo json_encode($repo); ?>);

        new ApplicationRouter({el: $('.site-container')});
        Backbone.history.start();
    }
);

define(['jquery', 'underscore', 'backbone', 'handlebars', 'text!templates/NavBar.html', 'models/repo'], 
    function($, _, Backbone, Handlebars, template, repoModel){
        // repoModel has values set by index.php
        
        return Backbone.View.extend({
            template: Handlebars.compile(template),
            initialize: function(options){

            }
        });
    }
);

これにより、何がコンストラクターで何がインスタンスなのか、本当に混乱するのではないかと心配しています。

終わり

ここまで読んだあなたはスゴイ!お時間を割いていただきありがとうございます。

4

3 に答える 3

4

私の場合、オプション 3を好みます。ただし、混乱を避けるために、すべてのシングルトン インスタンスを という名前の独自のフォルダーに配置しましinstancesた。また、私は をモジュールmodel/collectionから分離する傾向があります。instance

次に、それらを呼び出すだけです。

define([
  "instance/photos"
], function( photos ) { /* do stuff */ });

すべてのモジュールがその依存関係を定義することを強制されるため、私はこのオプションを好みます (たとえば、名前空間ではそうではありません)。ソリューション 2 で問題は解決できますが、AMD を使用している場合は、モジュールをできるだけ小さくしたいと思います。また、モジュールを小さく保つことで単体テストが容易になります。

最後に、単体テストについてですが、単体テスト内でモック データを使用するようにインスタンスを再定義するだけです。したがって、間違いなく、オプション 3 です。

このパターンの例は、私が ATM で作業しているオープン ソース アプリで確認できます: https://github.com/iplanwebsites/newtab-bookmarks/tree/master/app

于 2013-02-14T20:01:31.893 に答える
1

このサンプルレポを見てみましょうhttps://github.com/tbranyen/github-viewer

バックボーン ボイラー プレートの動作例です ( https://github.com/tbranyen/backbone-boilerplate )

Backbone Boiler プレートは多くの不必要な綿毛を処理しますが、これが本当に役立つのは、複雑な JavaScript アプリを開発するための一般的なパターンについて明確な指示を与えることです。

あなたの質問にもっと具体的に答えるために、今日の後半に戻ってくるようにします(誰かが私を打ち負かさなければ:)

于 2013-02-14T20:02:16.507 に答える
1

私は解決策 1 を好みます。一般的にsingletonsの使用を避ける のは良いことであり、特に RequireJS を使用しているため、globals の使用も避けるべきです。

解決策 1 について考えられるいくつかの利点を次に示します。

これにより、ビュー コードが読みやすくなります。モジュールを初めて見た人は、モジュールがinitializeどのモデルを使用しているかを見ればすぐにわかります。グローバルを使用すると、ファイル内の 500 行下の何かにアクセスする可能性があります。

これにより、ビュー コードの単体テストを簡単に記述できます。テストで偽のモデルを渡す可能性があるためです。

于 2013-02-14T21:19:33.020 に答える