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
ライブなデバッグが可能になっています。
