0

私は Backbone.js を初めて使用し、モデルとビューの関係の適切なアーキテクチャを理解するのに苦労しています。

入力ボックスと、その入力ボックスの内容を取得してサーバーに送信するモデルを保持するビューがあります。

私の問題は、ビューがモデル データを更新するためのリクエストをトリガーする目立たない DOM イベント ( input.change. 場合によっては、コード自体がモデルに更新をサーバーに送信するように要求する必要があります。

私はこれまで、この問題に対する 3 つの解決策を考えてきました。

  • 入力要素のkeypressイベントでモデルを更新します

  • get_input_value()ビューがモデルで初期化されたら、入力ボックスの値を返す' ' と呼ばれる関数をビューに更新/モデルに追加します。

  • アプリケーションがサーバーを更新するためにモデルを要求する必要がある場合は常に、ユーザーがビューに入力したすべての情報をモデルに更新するビュー内の関数を最初に呼び出します。

これは単純化された例であることに注意してください。ビューには子ビューも含まれており、そのすべてがユーザーが操作できる多くの要素を保持しています。サーバーを更新できるように、このすべての情報でモデルを更新する必要があります。

どんな助けや意見も歓迎します! 本当にありがとう!

編集 :::

machineghost の応答に基づいて、この問題を正しく説明していないことがわかりました。

DOM イベントがありますが、問題は、モデルを使用するビュー内から発生するとは限らないことです。ルーターまたは別のビューから発生し、グローバル イベント ハンドラーによってトリガーされる場合があります。さらに、1:1 のビューとモデルの関係はありません。このモデルは、モデルをさまざまな方法で表現する複数のビューで使用されます。したがって、この場合、サーバーを更新するコマンドはビューを経由するのではなく、モデル自体に送信する必要があるようです。その場合、モデルは「ビューと同期してください!」と言うことができなければなりません。

しかし、ルールを破らずにこれを行う方法がわかりません。これにより、アーキテクチャに関する他の問題が発生します...

4

1 に答える 1

4

これは一種の主観的な質問なので、これが私の 2 セントを吐き出しているように見える場合はご容赦ください。そして、あなたの質問に答える前に、私はあなたのことについて少し懐疑的であることを認めなければなりません:

目立たないDOMイベントが常にあるとは限りません

ユーザーができるほとんどのことは、監視できるイベントをトリガーするためです。たとえば、ユーザーがテキスト入力を変更するまで待ちたい場合はchange、 だけでなく、(ご指摘のとおり) さまざまなkey*イベントに加えて、blur(この種のことで一般的に使用される) があります。3(+) の間では、常にユーザーのアクションに適切に応答できる必要があります。DOM イベントから完全に独立しているのは、(たとえば) テキスト入力の内容を 3 秒ごとに保存する必要がある場合のみです。

だから、あなたの詳細を知らずに、私は何かが魚のにおいがすることを指摘しなければなりません. とにかく、あなたの実際の質問に関しては、あなたの考えに対する私の見解は次のとおりです。

入力要素のキー押下イベントでモデルを更新します

これは確かに機能しますが、ビューを使用して実際のイベント処理/モデル設定を行うようにしてください。モデルに onKeyPress ハンドラを接続するのは悪い考えです

全体として、このアプローチは非常に標準的であり、バックボーン パラダイムに適合します。

ビューがモデルで初期化されたら、入力ボックスの値を返す「get_input_value()」という関数をビューに更新/モデルに追加させます。

これがあなたの問題にどのように役立つかはよくわかりません。さらに、懸念を間違った場所に置いているようです。モデルは(理想的には)DOMとは何の関係もないはずです。

アプリケーションがサーバーを更新するためにモデルを要求する必要がある場合は常に、ユーザーがビューに入力したすべての情報をモデルに更新するビュー内の関数を最初に呼び出します。

保存は5分ごとに行われていますか?そうでない場合は、ユーザーのアクションに応答して発生していると考えられ、イベント ハンドラーを使用して応答する必要があります。

ただし、同期をユーザー アクションから独立させる必要がある場合は、カスタム イベントを使用して管理することをお勧めします。つまり、モデルの同期メソッドにthis.trigger('preSync'). 次に、そのモデルを使用するすべてのビューは、何らかのupdateMyModelValueメソッドをバインドできます。this.model.on('preSync', this.updateMyModelValue, this);.

この方法では、モデル コードが DOM と直接対話することはまったくありません。代わりに、心配するはずのもの (データ) だけを心配し、ビューは DOM からそのデータを更新する必要があるときに注意を払います。

それが役立つことを願っています。

*編集(質問の編集に応じて) *

その場合、モデルは「ビューと同期してください!」と言うことができなければなりません。

モデルが言うバックボーンの一般的な方法は...まあ、そのビューに対するほとんどすべてはイベントを通じてです。

(技術的には、モデル自体でモデルのビューのリスト維持し、そのリストを繰り返し処理して、ビューに何かを行うように指示することができます。バックボーンは、それを行うのに十分なほど意見がありません。ただし、保守性の観点からは、私には恐ろしいアプローチのように思えます。)

「事前同期」イベント (上記) の例は、この手法の使用方法を示しています。不明な点がある場合はコメントを返します。

同様に、次の問題がある場合:

  1. ビュー A がイベントをキャッチ
  2. ビュー B は、そのイベントに応答して何かを行う必要があります

基本的に次の 2 つのオプションがあります。

1) 2 つのビューを密結合できます。行ビューを作成するテーブル ビューがあり、それらの行で発生するイベントに応答する必要があるとします。行を作成するときにテーブル自体をオプションとして行に渡すことができます ( new Row({table:this}))。その後、それらの行がテーブルに「イベントが発生した」ことを伝える必要がある場合は、単に行を実行できますthis.options.table.informThatAnEventHappened()。テーブルとその行のように、2 つのビューが本質的に関連している場合、これは優れたアプローチです。そうでない場合、より良いアプローチは次のとおりです。

2) イベントを使用して、ビュー間で通信できます。ページの上部にタイトル div があり、「タイトル」テキスト入力が変更されるたびに更新する必要があるとしましょう...しかし、そのテキスト入力はページのずっと下にあり、概念的にはページのタイトル (設定は別として)。これら 2 つの要素 (およびそれらのビュー) の共通点は、タイトル自体のテキストであるデータです。

ここで、titleDivView と titleSettingInputView の両方が pageTitle モデルを共有しているとします。titleSettingInputView が を呼び出すthis.model.set('titleText', 'newTitle')と、titleDivView は をリッスンしthis.model.on('change:titleText', ...)、それに応じて適切に再レンダリングできます。このようにして、相互に関連するコードの絡み合った Web を作成することなく、2 つの完全に接続されておらず、分離されたビューが相互に対話できます。

そしてもちろん、バインドする便利な " change:title" イベントがない場合は、上で説明したカスタム " presync" イベントのように、いつでも独自のイベントを作成できます。

于 2012-07-20T00:52:46.170 に答える