1 00:00:07,640 --> 00:00:11,920 こんにちは、この講義では Seaside でのコンポーネントの 2 00:00:12,080 --> 00:00:14,480 合成のパワーを見ようと思います。 3 00:00:14,640 --> 00:00:18,360 再利用可能で状態を持つコンポーネントを 定義しました。 4 00:00:18,520 --> 00:00:21,760 そこで それらのコンポーネントを組み合わせて 5 00:00:21,920 --> 00:00:25,200 複雑なアプリケーションを構築します。 前にも言った通り 6 00:00:25,360 --> 00:00:27,120 アプリケーションとはルートコンポーネントです。 7 00:00:27,280 --> 00:00:31,760 アプリケーションのライブなデバッグを 楽しんでみましょう。 8 00:00:31,920 --> 00:00:35,240 Seaside でのコンポーネント合成の 9 00:00:35,400 --> 00:00:37,480 3 つの重要なメカニズムを復習します。 10 00:00:37,640 --> 00:00:40,080 1つ目は、コンポーネントの集約です。 11 00:00:40,240 --> 00:00:42,880 覚えているでしょうか 以前 2 つのカウンターを定義しました。 12 00:00:43,040 --> 00:00:46,000 1 つは通常の、こんな感じのカウンターと 13 00:00:46,160 --> 00:00:49,800 もう 1 つは、ツイッターのカウンターでした。 14 00:00:49,960 --> 00:00:51,000 よろしいですか? 15 00:00:51,160 --> 00:00:56,080 カウンターのコンポーネンントを 1 つのビューに集約して 16 00:00:56,280 --> 00:00:58,280 マルチカウンターアプリケーションを 構築するには、どうしたらよいでしょう? 17 00:00:58,440 --> 00:01:00,720 1 つのページ内に沢山のカウンターを 表示したいのです。 18 00:01:00,880 --> 00:01:03,360 例えば、この + をクリックすると 19 00:01:03,520 --> 00:01:06,680 このカウンターの値のみが増加します。 いいですね? 20 00:01:06,840 --> 00:01:11,080 沢山のコンポーネントを同じページに 集約するのは簡単です。 21 00:01:11,240 --> 00:01:13,800 これを Seaside ではどうするのでしょう? とても単純です。 22 00:01:13,960 --> 00:01:17,400 いつもの通り コンポーネントのサブクラスを定義します。 23 00:01:17,560 --> 00:01:19,720 WAMultiCounter です。 24 00:01:19,880 --> 00:01:23,080 インスタンス変数として、counters を定義します。 カウンターのコレクションです。 25 00:01:23,240 --> 00:01:28,480 initialize メソッドでは ここでは 5 つのカウンターのコレクションを作ります。 26 00:01:29,520 --> 00:01:30,440 いいですか? 27 00:01:30,600 --> 00:01:34,840 そして renderContentOn: メソッドを定義します。 28 00:01:35,000 --> 00:01:38,920 counters コレクションを do: で列挙します。 29 00:01:39,080 --> 00:01:42,400 そして各カウンターにそれぞれ 30 00:01:42,560 --> 00:01:47,000 html オブジェクトで描画するようにします。 render: という特別なメソッドを使います。 31 00:01:47,160 --> 00:01:50,680 render: メソッドは html オブジェクトのメソッドで 32 00:01:50,840 --> 00:01:55,560 コンポーネントを与えて それを自分自身に描画します。 33 00:01:55,720 --> 00:01:58,640 1 つ重要なメソッドがあります。 children です。 34 00:01:58,800 --> 00:02:02,640 コンポーネントが他のコンポーネントを持つ時には 35 00:02:02,800 --> 00:02:05,560 それらを renderContentOn: で描画するために 36 00:02:05,720 --> 00:02:09,800 内部のコンポーネントを宣言しなければなりません。 そして children メソッドが 37 00:02:09,960 --> 00:02:11,760 それらのコンポーネントのコレクションを 構築しなければなりません。 38 00:02:11,920 --> 00:02:15,440 そのコンポーネントが描画すべき 全てのコンポーネントです。 39 00:02:15,600 --> 00:02:18,800 ここでは counters コレクションを使います。 40 00:02:18,960 --> 00:02:21,680 このメソッドを定義することは重要です。 41 00:02:22,600 --> 00:02:25,560 というわけで、コンポーネントの集約 42 00:02:25,720 --> 00:02:27,840 による合成の基本ルールは簡単です。 43 00:02:28,000 --> 00:02:30,920 あるコンポーネントがそのサブコンポーネントを 44 00:02:31,080 --> 00:02:35,680 インスタンス変数に持ちます。 今回の例では counters です。いいですね? 45 00:02:35,840 --> 00:02:38,440 そして renderContentOn: メソッドでは 46 00:02:38,600 --> 00:02:41,760 html オブジェクトに 47 00:02:41,920 --> 00:02:46,600 render: メッセージを送り 各サブコンポーネントを描画します。 48 00:02:47,480 --> 00:02:49,440 そして children メソッドを再定義して 49 00:02:49,600 --> 00:02:52,000 全てのサブコンポーネントを宣言します。 50 00:02:53,080 --> 00:02:54,480 この 3 つは必須です。 51 00:02:57,240 --> 00:03:00,000 異なる種類のサブコンポーネントを 集約することもできます。 52 00:03:00,160 --> 00:03:02,280 同じ種類である必要はありません。 53 00:03:02,440 --> 00:03:06,800 これまでは単純にカウンターを 組み合わせただけですが 54 00:03:06,960 --> 00:03:09,920 次はアプリケーションを作ります。 MyApp コンポーネントです。 55 00:03:10,080 --> 00:03:12,520 initialize メソッドでは コレクションを作りますが 56 00:03:12,680 --> 00:03:15,320 今回はコレクションに 57 00:03:15,480 --> 00:03:19,200 Greeter(挨拶)アプリケーションを入れます。 前の講義で使ったものです。 58 00:03:19,360 --> 00:03:22,600 そしてツイッターカウンターとカウンターの 3 つのコンポーネントです。 59 00:03:22,760 --> 00:03:25,680 children メソッドは 60 00:03:25,840 --> 00:03:29,200 全てのサブコンポーネントを作り 61 00:03:29,360 --> 00:03:30,960 renderContextOn: では 62 00:03:31,120 --> 00:03:35,560 children を列挙して 自分を描画するようにします。 63 00:03:35,720 --> 00:03:37,880 つまり html render: each をします。 64 00:03:38,040 --> 00:03:40,480 つまり、Greeter、ツイッターカウンター そしてカウンターについて 65 00:03:40,640 --> 00:03:43,400 html render: します。 66 00:03:43,560 --> 00:03:44,800 どうなるか見てみましょう。 67 00:03:44,960 --> 00:03:49,880 ここに Greeter コンポーネントがあります。 ウェブページ上に表示されています。 68 00:03:50,040 --> 00:03:52,840 ここに、ツイッターカウンターが表示されて 69 00:03:53,000 --> 00:03:55,240 通常のカンターはここに表示されています。 70 00:03:55,400 --> 00:03:58,640 これでコンポーネントを合成して それぞれが独立して動作します。 71 00:03:58,800 --> 00:04:00,960 + をクリックしたり Say Hello をクリックしたりなど 72 00:04:01,120 --> 00:04:02,840 コンポーネントは完璧に動きます。 73 00:04:04,880 --> 00:04:08,000 では、もう 1 つ次のステージに進みましょう。 74 00:04:08,160 --> 00:04:12,200 Webページ上に 一度に全部のコンポーネントが欲しいのではなく 75 00:04:12,360 --> 00:04:15,720 毎回 1 つずつ表示したいとします。 例えば、メニューでどのサブコンポーネントを 76 00:04:15,880 --> 00:04:17,560 表示するか選択できるようにします。 77 00:04:17,720 --> 00:04:19,840 通常は、グリーターだけがあればよくて 78 00:04:20,000 --> 00:04:22,120 ここのツイッターカウンターをクリックした時だけ 79 00:04:22,280 --> 00:04:26,120 ツイッターカウンターを表示します。 80 00:04:26,280 --> 00:04:28,800 どうやって作ったらよいのでしょうか? 簡単です。 81 00:04:28,960 --> 00:04:31,880 MyApp アプリケーションに 82 00:04:32,040 --> 00:04:35,440 インスタンス変数 selectedChild を追加します。 83 00:04:35,600 --> 00:04:38,760 デフォルトでは最初のサブコンポーネントで 84 00:04:38,920 --> 00:04:40,960 初期化します。 85 00:04:41,120 --> 00:04:44,280 renderContentOn: メソッドを修正して 86 00:04:44,440 --> 00:04:46,640 メニューを表示します。 87 00:04:46,800 --> 00:04:50,680 どのサブコンポーネントを表示するかを 選択することができるようにします。 88 00:04:50,840 --> 00:04:55,000 そして、 html render: をします。 ただし、表示したいサブコンポーネントだけです。 89 00:04:55,160 --> 00:04:56,520 とても簡単です。 90 00:04:56,680 --> 00:05:00,440 メニューでは順序なしリストを生成して 91 00:05:00,600 --> 00:05:04,120 全てのサブコンポーネントを 92 00:05:04,280 --> 00:05:06,680 インデックス付きで列挙して 93 00:05:08,160 --> 00:05:11,480 サブコンポーネントごとにリスト要素を生成します。 94 00:05:11,640 --> 00:05:13,680 ここでアンカーを生成します。 95 00:05:13,840 --> 00:05:17,480 アンカーはクリック可能なリンクで 96 00:05:17,640 --> 00:05:22,600 クリックするとコールバックが呼ばれます。 このブロックです。 97 00:05:22,760 --> 00:05:27,600 つまり、仕組みは簡単で ユーザーに選択されたコンポーネントは 98 00:05:27,760 --> 00:05:31,480 self children はコレクションなので 99 00:05:31,640 --> 00:05:33,320 self children at: i 100 00:05:33,480 --> 00:05:35,000 となります。 101 00:05:35,160 --> 00:05:38,200 いいですか? ここで i は 102 00:05:38,360 --> 00:05:41,640 self children の中での 103 00:05:41,800 --> 00:05:43,360 インデックスです。 104 00:05:45,200 --> 00:05:49,680 全てのサブコンポーネントを列挙して 105 00:05:49,840 --> 00:05:52,320 どのサブコンポーネントを表示するか あるいは表示しないのかを 106 00:05:52,480 --> 00:05:54,600 制御することはとても簡単なのです。 107 00:05:56,080 --> 00:05:59,640 2 つ目の合成のメカニズムは コールアンサー と呼ばれるものです。 108 00:05:59,800 --> 00:06:02,080 これまでサブコンポーネントの集約を 見てきましたが 109 00:06:02,240 --> 00:06:05,800 これからコールアンサーメカニズムを 見ていきます。 110 00:06:05,960 --> 00:06:09,960 コンポーネント A のコードで 111 00:06:10,120 --> 00:06:14,280 こんなコードを書くことを 112 00:06:15,040 --> 00:06:19,120 コンポーネント A が コンポーネント B をコールする、と言います。 113 00:06:19,280 --> 00:06:24,240 何が起こるかというと、ウェブページ上で コンポーネントB がコンポーネントAを覆い隠して 114 00:06:24,400 --> 00:06:26,120 処理をします。 115 00:06:26,280 --> 00:06:28,880 しばらくするとコンポーネント B が 「もう自分の処理は終わりです。」 116 00:06:29,040 --> 00:06:31,200 「アンサーをして結果を返します。」 と言います。 117 00:06:31,360 --> 00:06:33,760 ここで、結果は☆印です。 118 00:06:33,920 --> 00:06:36,440 そしてこの結果が X に保存されます。 119 00:06:37,320 --> 00:06:40,080 call component: B の結果として。 120 00:06:40,240 --> 00:06:43,280 ここで、コンポーネント A が ウェブページ上にまた表示されて 121 00:06:43,440 --> 00:06:46,080 コンポーネント A はこの結果を使って 何かをすることができます。 122 00:06:46,720 --> 00:06:48,000 例をお見せしましょう。 123 00:06:48,160 --> 00:06:51,760 ここにコンポーネントがあります。 カウンターです。 124 00:06:51,920 --> 00:06:54,920 ここに Set Value ボタンを追加してあります。 125 00:06:55,080 --> 00:06:57,440 Set Value をクリックするとユーザーは 126 00:06:57,600 --> 00:06:59,560 カウンターの新しい値を入力できるとします。 127 00:06:59,720 --> 00:07:03,440 Set Value をクリックすると 新しいコンポーネントが表示されて 128 00:07:03,600 --> 00:07:07,000 Greeter コンポーネントのように 何かを入力することができて 129 00:07:07,160 --> 00:07:10,360 OK をクリックすると それをカウンターの新しい値とします。 130 00:07:10,520 --> 00:07:14,120 そしてカウンターコンポーネントに戻ります。 131 00:07:14,280 --> 00:07:18,080 ここでカウンターの値はさきほどユーザーが 入力した値になっています。 132 00:07:18,280 --> 00:07:19,600 いいですか? 133 00:07:19,760 --> 00:07:22,080 これらの一連のコンポーネントを 134 00:07:23,000 --> 00:07:24,640 どう実装するのでしょう? 135 00:07:24,800 --> 00:07:29,200 まず、ツイッターカウンターです。 renderContentOn: メソッドに 136 00:07:29,360 --> 00:07:33,320 ボタンを追加します。 137 00:07:33,480 --> 00:07:37,160 Set Value ボタンです。 138 00:07:37,320 --> 00:07:41,000 このボタンをクリックすると このコールバックが実行されます。 139 00:07:41,160 --> 00:07:43,960 setCountToUserValue メソッドです。 140 00:07:44,120 --> 00:07:46,600 SetCountToUserValue は ここで定義されています。 141 00:07:46,760 --> 00:07:50,120 そこでは ダイアログボックスを用意します。 142 00:07:50,280 --> 00:07:53,920 Seaside のダイアログボックス コンポーネントを使います。 143 00:07:54,080 --> 00:07:56,000 ここでダイアログボックスを構成します。 144 00:07:56,160 --> 00:07:59,320 「Enter a new value for the counter」 (カウンターの新しい値を入力してください) 145 00:07:59,480 --> 00:08:02,200 デフォルト値は 0 で OK ボタンが必要です。 146 00:08:02,840 --> 00:08:04,320 次にやることは 147 00:08:04,480 --> 00:08:07,080 この行です。 この行が興味深い要素です。 148 00:08:07,840 --> 00:08:09,040 ここです。 149 00:08:10,200 --> 00:08:13,400 ここで、このコンポーネント、つまり self は 150 00:08:13,560 --> 00:08:15,800 (覚えていますか? self はツイッターカウンターです) 151 00:08:15,960 --> 00:08:19,480 さきほど構築したダイアログボックスをコールします。 152 00:08:19,640 --> 00:08:21,080 そして結果を受け取ります。 153 00:08:21,720 --> 00:08:24,360 結果はカウンターの新しいカウント値に使います。 154 00:08:24,520 --> 00:08:27,280 そして最後に 155 00:08:27,440 --> 00:08:29,800 count つまりこのカウンタの値は 156 00:08:29,960 --> 00:08:33,560 ユーザーから入力された値を数値として 新しい値とします。 157 00:08:34,520 --> 00:08:35,480 とても単純です。 158 00:08:35,920 --> 00:08:38,200 内部的には この WAInputDialog の動作を 159 00:08:38,400 --> 00:08:40,560 確認することができます。 160 00:08:40,720 --> 00:08:44,760 Seaside の再利用可能なコンポーネントで とても古典的なものですが 161 00:08:44,920 --> 00:08:47,000 1 つ特別な機能があります。 162 00:08:47,160 --> 00:08:51,320 それは、answer: メソッドで 結果を送り返すことです。 163 00:08:52,080 --> 00:08:55,000 このコンポーネントの 164 00:08:55,160 --> 00:08:56,720 renderContentOn: メソッドを見ると 165 00:08:56,880 --> 00:08:59,720 OK ボタンをクリックすると 166 00:08:59,880 --> 00:09:02,040 それは実際には submit ボタンで 167 00:09:02,200 --> 00:09:06,280 コールバックとなるブロックを持っています。 そのコールバックでは 168 00:09:06,960 --> 00:09:10,560 self answer: value をします。 169 00:09:11,040 --> 00:09:15,120 つまり、このコンポーネントは結果を 170 00:09:15,280 --> 00:09:18,520 自分をコールしたコンポーネントに 送るということです。 171 00:09:18,680 --> 00:09:22,440 実際、コールされた場所に制御を戻し 172 00:09:22,600 --> 00:09:24,520 結果を送ります。 173 00:09:25,760 --> 00:09:27,400 コール/アンサーメカニズムを見てきました。 174 00:09:27,560 --> 00:09:30,440 最後のコンポーネント合成のメカニズムを 見ようと思います。 175 00:09:30,600 --> 00:09:33,120 タスクメカニズムです。 176 00:09:33,960 --> 00:09:35,160 本当に、とても簡単です。 177 00:09:35,320 --> 00:09:37,880 タスクはコンポーネントに似ていますが UI 部品ではありません。 178 00:09:38,040 --> 00:09:41,320 したがって、renderContentOn: も HTML の生成もありません。 179 00:09:41,480 --> 00:09:44,000 複数のコンポーネントを指揮して 180 00:09:44,160 --> 00:09:48,640 時間の経過に従って どう実行していくかを記述します。 181 00:09:48,800 --> 00:09:51,480 まず最初にこのコンポーネントが実行して 次にあのコンポーネントで、という具合に。 182 00:09:51,640 --> 00:09:55,960 スクリーンの裏側のコールアンサー のようなものです。 183 00:09:56,120 --> 00:09:58,920 Adder というタスクを定義します。 184 00:09:59,080 --> 00:10:02,120 全てのタスクは go メソッドを持っています。 185 00:10:02,280 --> 00:10:04,680 ここで、例えばこのタスクでは 186 00:10:04,840 --> 00:10:09,800 ユーザーに数値を入力するよう訊きます。 self request: firstNumber です。 187 00:10:09,960 --> 00:10:13,360 そして2番目の数値を入力するよう訊いて value2 とします。 188 00:10:13,520 --> 00:10:17,160 そして、それら 2 つの数の合計を 189 00:10:17,320 --> 00:10:21,120 ここで伝えます。いいですね? 190 00:10:21,280 --> 00:10:25,240 最後の行では、このコンポーネントを アプリケーションとして登録します。 191 00:10:25,400 --> 00:10:28,240 ブラウザからアクセスするための 古典的なウェブアプリケーションです。 192 00:10:29,920 --> 00:10:31,560 内部では 193 00:10:31,720 --> 00:10:34,680 request: メソッドはどのように 実装されているのでしょう? 194 00:10:34,840 --> 00:10:36,360 request: メソッドは 195 00:10:36,520 --> 00:10:41,600 内部的にはコールアンサーを使っています。 196 00:10:41,800 --> 00:10:44,040 前のスライドでの 197 00:10:44,200 --> 00:10:47,640 ここで request: をすると、内部的に 198 00:10:47,800 --> 00:10:50,120 もう 1 つのコンポーネンントをコールします。 199 00:10:50,280 --> 00:10:54,520 元からあるものではなくて WAInputDialog コンポーネントをコールします。 200 00:10:54,680 --> 00:10:56,560 そのコンポーネントが文字列を表示して 201 00:10:56,720 --> 00:10:59,920 このコンポーネントがリクエストした側に 結果を返します。 202 00:11:00,080 --> 00:11:03,440 この例では、誰がリクエストをしたでしょう? Adder です。 203 00:11:03,600 --> 00:11:06,440 なので、Adder が値を value1 に受け取ります。 204 00:11:06,600 --> 00:11:09,960 同じことが value2 にもあって そして inform: します。 205 00:11:10,120 --> 00:11:13,440 inform: がどう実装されているかを見ると 206 00:11:13,600 --> 00:11:17,160 inform: もコール/アンサーを使っていますが 別のコンポーネントで行なっています。 207 00:11:17,320 --> 00:11:19,680 FormDialog です。 208 00:11:19,840 --> 00:11:22,360 self call: FormDialog すると 209 00:11:22,520 --> 00:11:25,760 文字列を OK ボタン付きで表示して 210 00:11:25,920 --> 00:11:28,040 「はい、これで彼はこの文字列を見ました」 と言います。 211 00:11:28,800 --> 00:11:31,040 これらの合成の全ての形態において 212 00:11:31,240 --> 00:11:33,120 知っておくべきことは 213 00:11:33,280 --> 00:11:36,080 HTTP リクエストや URL や 214 00:11:36,240 --> 00:11:39,880 パースや設定などについて一切話さなかった ということです。 215 00:11:40,040 --> 00:11:42,880 リクエストのルーティングについても 全く話していません。 216 00:11:43,040 --> 00:11:46,680 次のページへのリンクなどは 一切何もしていません。 217 00:11:46,840 --> 00:11:50,160 お話したことは、コンポーネントのことです。 218 00:11:50,320 --> 00:11:52,640 状態を持つコンポーネントを使って 合成できること 219 00:11:52,800 --> 00:11:55,000 3 つの形態の合成があること 220 00:11:55,160 --> 00:11:57,120 コンポーネントは他のコンポーネントを カプセル化すること 221 00:11:57,280 --> 00:11:59,480 コンポーネントは他のコンポーネントを コールすることができること 222 00:11:59,640 --> 00:12:03,480 そして Seaside でワークフローを定義して コンポーネントを 1 本の線として繋げることです。 223 00:12:03,640 --> 00:12:04,920 これはとても強力で 224 00:12:05,080 --> 00:12:07,840 ライブなデバッグが可能になっています。