4

私は大きな Backbone.js アプリケーションに取り組んでいます。コードは、 を使用してモジュール構造になってrequire.jsいます。現在、これを行う多くのバックボーン コードとチュートリアルを目にします。

window.app = ( window.app || {} );

モデル定義と Collection インスタンスをそのグローバル オブジェクトに割り当てた後、次のようになります。

Task = Backbone.Model.extend({ /*...*/ });
Tasks = Backbone.Collection.extend({ /*...*/ }); 

window.app.Task = Task;
window.app.Tasks = new Tasks();
// do this with all your models and collections

シンプルで、いつどこでコレクションをインスタンス化する必要がないかという点で、このアプローチが気に入っています。しかし、最初にコードを小さなビットに分割し、グローバル変数にまとめて代入するのは、どういうわけか間違っているようrequire.jsです (ただし、グローバル変数は JavaScript では一般的に悪いコードスタイルです)。

では、これについてどう思いますか?このアプローチの長所と短所は何ですか?Backbone でオブジェクトをどのように処理しますか?

4

3 に答える 3

6

まず第一に、すべてのモデルを独自の名前空間にラップできるため、グローバル名前空間を汚染することはそれほど大きな問題ではありません。

app = (app || {} );
app.Task = Backbone.Model.extend({ /*...*/ });
app.Tasks = Backbone.Collection.extend({ Model:app.Zask }); 

requirejs に関しては、プロジェクトのサイズによって異なります。小規模なプロジェクトでは、なくてもよいと思います。requirejs を使用する利点は、名前空間の汚染を防ぐことではなく、モジュールの依存関係を常に確認できるため、保守性が向上することです。モジュールをテストし、そのすべての依存関係をモックアウトできるため、より優れた単体テストを作成できます。したがって、上記の例のような構造から大規模なバックボーン アプリを次のように再構築します。

モデル/Task.js

define(function () {
  return Backbone.Model.extend({ /*...*/ });
});

コレクション/Tasks.js

define([models/Task], function (Task) {
  return Backbone.Collection.extend({ Model:app.Task }); 
});

app.js

define([collections/Tasks], function (Tasks) {
  var tasks = new Tasks();
  tasks.fetch();
});
于 2012-09-07T06:50:24.003 に答える
1

私はグローバルが JavaScript で悪いことに同意しません。ほとんどの言語でグローバルが必要です。何かをインポートしたら、それを参照できるようにする必要があります。Java に似た言語は、すべてのクラス名を巨大なグローバル ヒープに投げ込むだけです。しかし、これらの言語ではクラス (クラス名、クラス参照) が変数ではないため、そうであることに気付くことはありません。

JavaScript クラス (またはクラスを模倣するふりをするもの) では、変数に割り当てる単なるオブジェクトです。したがって、コードの他の部分でそれらを参照できるようにするのはあなた次第です。

実際にあなたの例では、モデル定義とコレクション インスタンス (おそらくシングルトン) をグローバル スコープに割り当てます。モデル定義については、これが正しい唯一の方法だと思います (おそらく、 などの名前空間を追加しますwindow.app.model.Task = Task)。2 番目のケースでは、純粋主義者の見解は、あまり良くないということかもしれません。のようなことをしてから、シングルトンを返すwindow.app.collection.Tasks = Tasks静的メソッドを定義したいと思います。Tasks.getinstance()または、シングルトンをグローバルスコープにも配置することはあまり良くありません (ただし、コーディングは少なくなります) window.app.singletons.Tasks = Tasks()

最後に、すべてが適切にスコープされていることを確認してください。このコード (ブラウザーで実行) は、Task および Tasks グローバル オブジェクトも作成します。このすべてを関数でラップして、使用しますvar

(function (app) {
  var Task = Backbone.Model.extend({ /*....*/ }),
  Tasks = Backbone.Collection.extend({ /*....*/ }, {
    getInstance: function () {
      if (!this.instance) {
        this.instance = new Tasks();
      }
      return this.instance;
    }
  });

  if (!app.models) {
    app.models = {};
  }
  if (!app.collections) {
    app.collections = {};
  }

  app.models.Task = Task;
  app.collections.Tasks = Tasks;
}(window.app));
于 2012-09-06T15:57:57.423 に答える
0

個人的には、AMD ソリューションに沿ったグローバル名前空間を汚染するつもりはありません。これは、基本的にやりたいことですが、モデルとコレクションを使用して、AMD モジュール間でリソースを共有することに関する投稿です。

また、Backbone Aura フレームワークのこの号の最後に、取得のためにコレクションとモデルを名前空間化するデータ モジュールの実装があります。先日、アプリでこの問題に遭遇したばかりで、これを実装する予定です。

于 2012-09-07T05:41:09.797 に答える