20

リッチ クライアントの Web サイト デザインに Om を使用することを検討しました。また、core.async を使用するのはこれが初めてです。チュートリアルを読むhttps://github.com/swannodette/om/wiki/Basic-Tutorial削除操作を処理するための core.async チャネルの使用法を見てきました (ハンドラーですべての作業を行うのではなく)。そのアイテムを含むリストを実際に操作したいアイテムレベルにカーソルがあるスコープで削除コールバックが宣言されたため、そのチャネルを削除に使用しただけであるという印象を受けました。

チャネルについてさらに洞察を得るために、Rich Hickey の講演http://www.infoq.com/presentations/clojure-core-asyncを見ました。そこで彼は、チャネルを使用してイベント コールバックからアプリケーション ロジックを取得することがいかに良いアイデアであるかを説明しています。これにより、チュートリアルの削除チャネルの実際の目的は、アプリケーションを構造化する方法を示すことだったのだろうかと疑問に思いました。もしそうなら、

  • そのパターンに関連するベスト プラクティスは何ですか?

  • あらゆる種類のイベントに対して個別のチャネルを作成する必要がありますか? つまり、コントローラを追加して新しいイベントを作成する場合、アプリケーションの別の場所でオブジェクトをグローバル状態に追加するために使用されるオブジェクト作成用の新しいチャネルも作成しますか?

  • アイテムのリストがあり、1 つのアイテムに詳細/簡潔な状態フラグがあるとしましょう。である場合detailed?trueより多くの情報を表示し、 である場合detailed?falseより少ない情報を表示します。カーソルで使用するオンクリック イベントを関連付けましたom/transact!(グローバル状態オブジェクト内のリスト項目へのビューです)。

(let [toggle-detail-handler 
      (fn [e]
        (om/transact! (get-in myitem [:state])
                      #(conj % {:detailed? (not (:detailed? %))})))]
  (html [:li {:on-click toggle-detail-handler}
         "..." ])) 

これは非常に簡潔なスニペットであり、コールバック イベントを実際のロジックの変更から分離する手段としてチャネルを使用することの全体的な利点は、最初は努力する価値がないように見えますが、より複雑な例の全体的な利点はこれを上回ります。しかし一方で、このような詳細ではないトグル用に追加のチャネルを導入すると、ソース コードにもかなりの負荷がかかるようです。

設計上の問題全体に関するヒントやヒント、またはその他の考えを提供し、それらを展望していただければ幸いです。私はそこで少し途方にくれた気がします。

4

1 に答える 1

16

チャネルを使用して、カーソルを介して通信できないコンポーネント間で通信します。

たとえば、次の場合にチャネルを使用します。

  • 通信するコンポーネントがアプリの状態を共有しない (たとえば、カーソルが階層データ構造の異なるブランチを指している)
  • アプリの状態の外でライブで伝達される変更 (たとえば、コンポーネント A がコンポーネント B のローカル状態を変更したいのに、コンポーネント B が A の子ではない場合) (そうでない場合は、 に渡すことでこれを行うことができ:stateますom/build)
  • Om コンポーネント ツリーの外にあるものと通信したい

「ドメイン状態」をアプリ状態アトムに保持し、GUI 状態をコンポーネントのローカル状態に保持することに注意してください。つまり、アプリの状態はレンダリングされるものであり、ローカルの状態は howです。(「方法」はどの部分も指します) たとえば、テキスト エディターを作成している場合、アプリの状態は編集中のドキュメントであり、ローカルの状態は編集中のページであり、太字が選択されているかどうかなどです。

[topic value]一般的に、ペアを配置する単一の通信チャネルを使用します。次に、pubsubを使用してメッセージをルーティングします。たとえば、(def p (async/pub ch first))トピックを使用してイベントをディスパッチしたり、トピックを(om/sub p my-ch :foo)含むメッセージを受信したりします。私は通常、この単一の通信チャネルを Om の共有状態に保存します。:foomy-ch

複数のチャネルを使用することもありますが、これは汎用的なメッセージングではなく、特定のパイプラインまたはワークフローを設定するために行います。たとえば、データ ストリームに対して処理を行う処理コンポーネントのパイプラインがある場合、これを Om アプリケーションに接続されたエンドポイントを持つ一連のチャネルとして設定できます。一般的な UI 開発では、これはまれです。また、Om コンポーネント用の Qt 風のシグナル/スロット システムをいじっています。共有シグナル チャネルを使用するか、各シグナルを独自のチャネルにするかをまだ実験中です。どちらのアプローチが優れているかはまだわかりません。

于 2014-06-10T14:23:21.897 に答える