17

私のアプリの多くの場所で、次のパターンが発生します。

  • ユーザーがナビゲーションをトリガーするリンクをクリックする
  • ビューをレンダリングするには、データを取得する必要があります
  • UI 設計では、データの取得中に「読み込み中」のスピナーを表示する必要があります
  • データが取得されたら、レンダリングされたビューを表示します

次の実装パターンの両方を試しました。

  1. ルーターがフェッチを処理する

    • ルーターはコンテナビューに読み込みスピナーを表示するように指示します
    • ルーターはコレクション/モデルをロードします
    • ルーターはコンテナビューに読み込みスピナーを非表示にするように指示します
    • ルーターはコレクション/モデルをビューに渡し、それをレンダリングします
  2. ビュー ハンドルの取得

    • ルーターはビューを作成してレンダリングするだけです
    • ビューは、必要なコレクションとモデルを取得します
    • ビューが最初にレンダリングされると、データがまだロードされているため、ロード スピナーが表示されます。
    • データが到着すると、モデル/コレクションがイベントを発生させ、ビューがそれらにバインドされるため、ビュー自体が再レンダリングされるため、読み込みスピナーが非表示になり、ビュー全体が表示されます

ルーターがモデル/コレクションフェッチロジックの巨大なボールになり、責任が大きすぎるように見えるので、私は#1を嫌います。#2 はより適切な責任の割り当てのように見えます (ルーターは表示するビューを決定するだけで、ビューは取得する必要があるデータを把握します) が、現在ステートフルであるため、ビューのレンダリングが少し複雑になります。

StackOverflow コミュニティはどう考えていますか? 1、2、または他の何か?

4

2 に答える 2

23

この投稿はかなり古いものですが、今日は以前にレビューしていたので、他の誰かがそれに出くわした場合に備えて:

私には、2つの別々の質問があります。

  1. データ取得の仕組みとその結果のビューのレンダリングは、ルーターまたはビューのどこで行われるべきですか?
  2. ビューは既に解決済みのモデルを期待するべきですか、それともまだロード中の可能性があるモデルに応答するべきですか?

私たちがそれを処理する方法の一部と、いくつかの個人的な好みが混在しています。

  1. どちらでもありませんが、私はルーターに寄りかかります。ルーターはルーティングを処理し、ビューは表示を処理する必要があり、別の何かがモデル/コレクション フェッチ ロジックのメカニズムとワークフローを処理する必要があります。これは、ルーターが基本的に委譲するコントローラーと呼ばれるものです。
  2. ユリがほのめかすように、「時々」は現実です。これはおそらくケースバイケースの決定だと思いますが、最終的には、ルーター/ビュー間ではなく、コントローラーとビュー間の契約になるはずです。

私はユリの箇条書きが好きですが、いくつかの注意点があります (インデントされた箇条書き):

  • ルーターは、ユーザーの送信先のみを知っています
  • 外側のビューは、ユーザーが何を表示する必要があるかのみを認識します (そのデータが与えられた場合)
    • 外側のビューが内側のビューのユース ケースに固有であり、別のビューによって「所有」されていると仮定します (クリーンアップのため)。
    • それ以外の一般的なコンテナー (「メイン」の場所へのレンダリングなど) の場合、ページ上の特定の「セクション」のビューを管理するコンポーネントがあると便利であることがわかりました。これをレンダラーと呼びます。
  • 内部ビューは、すべての小さな部分のみを表示する方法しか知りません (そして、他の場所で使用できます)。
  • レンダー関数は常に現時点で正しいものを表示します。
    • 汎用コンテナの場合、最終的にはレンダラーの責任になります

Renderer の主な理由は、ゴースト ビューを回避するために既存のビューをクリーンアップする、レンダリング時に一番上までスクロールする (MainContentRenderer がそれを行います)、この場合はスピナーを表示するなど、そのセクションに関連することを処理することです。

それがどのように見えるかの疑似コードっぽい例:

  • 一般的なコンテンツターゲット「メイン」(ユースケース固有の場合は、ビューのライフサイクル管理戦略に応じて、Yuri の例のように ComponentView を使用する方がよい場合があります)
  • 取得して待機する必要があるモデル
  • すでにロードされたモデルを受け入れるビュー

ルーター:

routes: {
    "profile": "showProfile"
},

showProfile: function() {
    return new ProfileController().showProfile();
}

プロファイルコントローラー:

showProfile: function() {
    //simple case
    var model = new Model();
    var deferredView = model.fetch.then(function() {
        return new View(model);
    };
    MainContentRenderer.renderDeferred(deferredView);
}

MainContentRenderer:

var currentView;

renderDeferred: function(deferredView) {
    showSpinner();
    deferredView.then(function(view) {
        this.closeSpinner();
        this.closeCurrentView();
        this.render(view);
    }
},

render: function(view) {
    currentView = view;
    $('#main-content').html(view.render().el);
}

closeCurrentView: function() {
    if (currentView and currentView.close()) {
        currentView.close();
    }
}

コントローラーの導入には、テスト容易性の追加の利点もあります。たとえば、URL 管理に関する検索の実行、結果ビューと新しい検索ビューの選択、キャッシュされた「最後の」検索結果と新しい検索の実行の選択には、複雑なルールがあります。すべてのフロー ロジックが正しいことを確認するために、コントローラー用の Jasmine テストがあります。また、これらのルールを管理するための独立した場所も提供します。

于 2013-02-28T05:18:07.270 に答える
7

私は、コンテナー、読み込みビュー、およびコンテンツ ビューの 3 つのビューで 2 番目のオプションを使用する傾向があります。つまり、コンテナーはルーターによってインスタンス化され、各レンダリング中に、表示する手元にあるもの (ルーターによって提供される場合もあれば、それ自体によって提供される場合もあります) を調べて、どのビューをインスタンス化するかを決定します。単純化した不自然な例:

ContainerView = Backbone.View.extend({

  initialize: function (options) {
    options.data.bind("reset", this.render, this);
  },

  render: function () {
    var view;

    // If the loading view is only shown once, e.g., splashing, then isReady()
    // may be better here.
    if (this.options.data.isLoading()) {
      view = LoadingView;
    } else {
      view = DataView;
    }

    this.$("div.content").html(new view().render().el);
  }

});

私がこのアプローチを気に入っている理由は次のとおりです。

  • ルーターは、ユーザーの送信先のみを認識しています。
  • 外側のビューは、ユーザーがを表示する必要があるか (そのデータが与えられた場合) のみを認識します。
  • 内側のビューは、すべての小さな部分のみを表示する方法しか知りません (そして、他の場所で使用できます)。と
  • レンダリング機能は、現時点で常に正しいものを表示します。

明確化: この場合のビューの目的は、表示する必要があるものをユーザーに最適に表示する方法を理解することです。この場合、ロード中のデータの一部はロード ビューで表示するのが最適であり、準備完了のデータはデータ ビューで表示するのが最適です。ほとんどの実際のビューは、実際にはさらに多くのビューで表示を構成しています。たとえば、ユーザーの承認に応じて、さまざまなアクション コンテナーが表示されます。

于 2012-05-30T01:01:11.113 に答える