﻿1
00:00:07,640 --> 00:00:11,920
Hello, in this sequence,
you'll see the power of Seaside,

2
00:00:12,080 --> 00:00:14,480
through the composition of components.

3
00:00:14,640 --> 00:00:18,360
We defined the reusable
and stateful components,

4
00:00:18,520 --> 00:00:21,760
now we'll see how we can
put these components together

5
00:00:21,920 --> 00:00:25,200
in order to build complex applications.
As we said, an application

6
00:00:25,360 --> 00:00:27,120
is a root component,

7
00:00:27,280 --> 00:00:31,760
so we benefit from debugging,
of live debugging of applications.

8
00:00:31,920 --> 00:00:35,240
We'll go back over
3 important mechanisms

9
00:00:35,400 --> 00:00:37,480
for composing components in Seaside.

10
00:00:37,640 --> 00:00:40,080
The first is component aggregation.

11
00:00:40,240 --> 00:00:42,880
Remember, we defined 2 counters,

12
00:00:43,040 --> 00:00:46,000
one normal counter,
which looked like this

13
00:00:46,160 --> 00:00:49,800
and a Twitter counter, here.

14
00:00:49,960 --> 00:00:51,000
OK?

15
00:00:51,160 --> 00:00:56,080
How can I now aggregate
a component counter

16
00:00:56,280 --> 00:00:58,280
with a view to building
a multi-counter application?

17
00:00:58,440 --> 00:01:00,720
I want to show lots
of counters on one page.

18
00:01:00,880 --> 00:01:03,360
When I click on this +, for example,

19
00:01:03,520 --> 00:01:06,680
it only increases the value
of this particular counter, OK?

20
00:01:06,840 --> 00:01:11,080
So, aggregating lots of components
on the same page, easily.

21
00:01:11,240 --> 00:01:13,800
So how do we do this in Seaside?
It's extremely simple.

22
00:01:13,960 --> 00:01:17,400
I'll define a component subclass,
which is always the same,

23
00:01:17,560 --> 00:01:19,720
which is called "WAMultiCounter",

24
00:01:19,880 --> 00:01:23,080
"instance variable counters",
defining a collection of counters.

25
00:01:23,240 --> 00:01:28,480
In "method initialize" I'll create
a collection of 5 counters, here.

26
00:01:29,520 --> 00:01:30,440
OK?

27
00:01:30,600 --> 00:01:34,840
And then I'll have the method
"rendercontentOn", here

28
00:01:35,000 --> 00:01:38,920
where I'll say I'll browse
my counter collection with a "do"

29
00:01:39,080 --> 00:01:42,400
and I'll ask each counter,
at least, the html object,

30
00:01:42,560 --> 00:01:47,000
to render each of the counters.
I use a special method, "render".

31
00:01:47,160 --> 00:01:50,680
This render method of the html object

32
00:01:50,840 --> 00:01:55,560
allows you to ask a component
to render itself, draw itself in html.

33
00:01:55,720 --> 00:01:58,640
We've an important method here
called "children",

34
00:01:58,800 --> 00:02:02,640
which means that when a component
encapsulates other components

35
00:02:02,800 --> 00:02:05,560
and asks them to render
in "renderContentOn",

36
00:02:05,720 --> 00:02:09,800
it has to declare them, and to do that
it has to render a collection

37
00:02:09,960 --> 00:02:11,760
of components in its method "children"

38
00:02:11,920 --> 00:02:15,440
which contains all the components
it's going to render, all its children.

39
00:02:15,600 --> 00:02:18,800
Here I'm rendering
the collection "counters".

40
00:02:18,960 --> 00:02:21,680
It's an important method to define.

41
00:02:22,600 --> 00:02:25,560
So, the basic rules
for aggregating components,

42
00:02:25,720 --> 00:02:27,840
composing components is easy.

43
00:02:28,000 --> 00:02:30,920
One component
will store its subcomponents

44
00:02:31,080 --> 00:02:35,680
in an instance variable.
In our example it's "counters", OK?

45
00:02:35,840 --> 00:02:38,440
It will then pass the "render" message

46
00:02:38,600 --> 00:02:41,760
to html,

47
00:02:41,920 --> 00:02:46,600
in its "renderContentOn" method,
asking each child to render itself.

48
00:02:47,480 --> 00:02:49,440
It will then redefine
the method "children"

49
00:02:49,600 --> 00:02:52,000
to declare all of its subcomponents.

50
00:02:53,080 --> 00:02:54,480
There are always these 3 parts.

51
00:02:57,240 --> 00:03:00,000
We can also aggregate
different subcomponents.

52
00:03:00,160 --> 00:03:02,280
They don't have to be the same type.

53
00:03:02,440 --> 00:03:06,800
Before, I only combined counters
and here we're going to have

54
00:03:06,960 --> 00:03:09,920
an application, a MyApp component.

55
00:03:10,080 --> 00:03:12,520
In the method "initialize"
it's a collection,

56
00:03:12,680 --> 00:03:15,320
except that in this collection I put

57
00:03:15,480 --> 00:03:19,200
the app "Greeter" that we used
in a previous sequence, which we saw,

58
00:03:19,360 --> 00:03:22,600
a Tweeter counter and a counter.
3 components.

59
00:03:22,760 --> 00:03:25,680
My method, "children" renders

60
00:03:25,840 --> 00:03:29,200
all the children, the subcomponents
of this MyApp component,

61
00:03:29,360 --> 00:03:30,960
and in "renderContentOn"

62
00:03:31,120 --> 00:03:35,560
I want to browse my children
and ask them to render themselves.

63
00:03:35,720 --> 00:03:37,880
So we do "html render: each"

64
00:03:38,040 --> 00:03:40,480
and I'll do "html render" of Greeter,

65
00:03:40,640 --> 00:03:43,400
the Twitter counter and counter.

66
00:03:43,560 --> 00:03:44,800
Let's see what we get.

67
00:03:44,960 --> 00:03:49,880
Here we have the Greeter component,
which is displayed on the Web page,

68
00:03:50,040 --> 00:03:52,840
we've the Twitter counter
displayed here,

69
00:03:53,000 --> 00:03:55,240
and the normal counter displayed here.

70
00:03:55,400 --> 00:03:58,640
We've composed the components
and they all work independently

71
00:03:58,800 --> 00:04:00,960
if I click on the +
and the "Say Hello" etc,

72
00:04:01,120 --> 00:04:02,840
the components work perfectly.

73
00:04:04,880 --> 00:04:08,000
So now, if you like,
there's one stage further.

74
00:04:08,160 --> 00:04:12,200
We don't want all the components
at once on the Web page.

75
00:04:12,360 --> 00:04:15,720
We want one at a time,
a menu, for example, to select

76
00:04:15,880 --> 00:04:17,560
which subcomponent
we want displayed.

77
00:04:17,720 --> 00:04:19,840
Typically,
I only want to show the Greeter

78
00:04:20,000 --> 00:04:22,120
and when I click on Twitter counter here,

79
00:04:22,280 --> 00:04:26,120
I'm only going to display
the Twitter counter.

80
00:04:26,280 --> 00:04:28,800
How do we make this application?
It's easy.

81
00:04:28,960 --> 00:04:31,880
I add an instance variable
in my MyApp application,

82
00:04:32,040 --> 00:04:35,440
which is called the selected
component, the selected child.

83
00:04:35,600 --> 00:04:38,760
By default, I'll initialize it

84
00:04:38,920 --> 00:04:40,960
to the first subcomponent,

85
00:04:41,120 --> 00:04:44,280
In the "renderContentOn" method,
here, I've modified it,

86
00:04:44,440 --> 00:04:46,640
I'll display one menu,

87
00:04:46,800 --> 00:04:50,680
giving me the possibility to select
which subcomponent I display,

88
00:04:50,840 --> 00:04:55,000
then I do "html render" but only
of the subcomponent I want to display.

89
00:04:55,160 --> 00:04:56,520
Quite simply.

90
00:04:56,680 --> 00:05:00,440
In the menu, I'll generate
one unordered list,

91
00:05:00,600 --> 00:05:04,120
I'll browse all of my subcomponents

92
00:05:04,280 --> 00:05:06,680
which I browse with an index, "i"

93
00:05:08,160 --> 00:05:11,480
and I generate a list element
for each child.

94
00:05:11,640 --> 00:05:13,680
Here, I'm going to generate an anchor,

95
00:05:13,840 --> 00:05:17,480
a clickable link,
and when I click on this link,

96
00:05:17,640 --> 00:05:22,600
it will trigger the callback,
the execution of this block, here.

97
00:05:22,760 --> 00:05:27,600
So we can say, it's easy,
the component selected by the user

98
00:05:27,760 --> 00:05:31,480
is the child number...
so "self children".

99
00:05:31,640 --> 00:05:33,320
Remember, it's a collection...

100
00:05:33,480 --> 00:05:35,000
"at: i"

101
00:05:35,160 --> 00:05:38,200
OK? And "i" here

102
00:05:38,360 --> 00:05:41,640
is no more nor less
than the number of the element

103
00:05:41,800 --> 00:05:43,360
in the "children" collection.

104
00:05:45,200 --> 00:05:49,680
So it's extremely easy to be able
to browse all of the subcomponents

105
00:05:49,840 --> 00:05:52,320
and to specifically generate,
to completely control

106
00:05:52,480 --> 00:05:54,600
what should and shouldn't
be displayed.

107
00:05:56,080 --> 00:05:59,640
We've a 2nd composition mechanism,
which is "call answer".

108
00:05:59,800 --> 00:06:02,080
We've seen components aggregation

109
00:06:02,240 --> 00:06:05,800
with subcomponents, and now we'll see
the "call answer" mechanism.

110
00:06:05,960 --> 00:06:09,960
If we imagine,
in the code of component A,

111
00:06:10,120 --> 00:06:14,280
we'll write something that looks
like this code here, we'll say,

112
00:06:15,040 --> 00:06:19,120
component A calls component B.
Call component B.

113
00:06:19,280 --> 00:06:24,240
What will happen is, component B
will mask component A on the Web page,

114
00:06:24,400 --> 00:06:26,120
it will carry out a treatment,

115
00:06:26,280 --> 00:06:28,880
and after a while, component B
will say, "I've done my treatment,

116
00:06:29,040 --> 00:06:31,200
"I'll do answer and give a result".

117
00:06:31,360 --> 00:06:33,760
Here the result is a star,

118
00:06:33,920 --> 00:06:36,440
and this result will be stored in X

119
00:06:37,320 --> 00:06:40,080
in the place of "call component B".

120
00:06:40,240 --> 00:06:43,280
Now, component B will reappear
on the Web page

121
00:06:43,440 --> 00:06:46,080
and component A can use this result
to do something.

122
00:06:46,720 --> 00:06:48,000
I'll show you an example.

123
00:06:48,160 --> 00:06:51,760
Here we have a component,
which was the counter.

124
00:06:51,920 --> 00:06:54,920
We've added a button,
here, "Set Value",

125
00:06:55,080 --> 00:06:57,440
We imagine that "Set Value"
allows the user

126
00:06:57,600 --> 00:06:59,560
to enter a new value for the counter.

127
00:06:59,720 --> 00:07:03,440
When we click on "Set Value"
a new component is displayed,

128
00:07:03,600 --> 00:07:07,000
which allows us to enter,
a bit like the Greeter component,

129
00:07:07,160 --> 00:07:10,360
we can enter a new value
for the counter, click on "OK"

130
00:07:10,520 --> 00:07:14,120
and when I click on "OK"
it goes back to our counter component

131
00:07:14,280 --> 00:07:18,080
but with the value entered here
by the user at the beginning.

132
00:07:18,280 --> 00:07:19,600
OK?

133
00:07:19,760 --> 00:07:22,080
So we've a series
of several components.

134
00:07:23,000 --> 00:07:24,640
How is this implemented?

135
00:07:24,800 --> 00:07:29,200
We've our Twitter counter
with its "renderContentOn" method.

136
00:07:29,360 --> 00:07:33,320
To its "renderContentOn" method
we'll add a button,

137
00:07:33,480 --> 00:07:37,160
a tbsButton, etc...
This button's called "Set Value", here.

138
00:07:37,320 --> 00:07:41,000
When we click on this button,
this callback will be executed.

139
00:07:41,160 --> 00:07:43,960
It's the "setCountToUserValue" method.

140
00:07:44,120 --> 00:07:46,600
SetCountToUser is defined here.

141
00:07:46,760 --> 00:07:50,120
What we do is we'll prepare
a dialogue box here.

142
00:07:50,280 --> 00:07:53,920
We'll use another component
made by Seaside, a dialogue box.

143
00:07:54,080 --> 00:07:56,000
which we'll configure here,

144
00:07:56,160 --> 00:07:59,320
in this instance with
"Enter a new value for the counter".

145
00:07:59,480 --> 00:08:02,200
The default setting is 0
and we've an OK button.

146
00:08:02,840 --> 00:08:04,320
What we'll do next...

147
00:08:04,480 --> 00:08:07,080
The really interesting
element is this line here...

148
00:08:07,840 --> 00:08:09,040
Here...

149
00:08:10,200 --> 00:08:13,400
We're going to say,
"current component", so "Self".

150
00:08:13,560 --> 00:08:15,800
Remember,
"Self" is the Twitter counter.

151
00:08:15,960 --> 00:08:19,480
"Call the dialogue box
we've just created,

152
00:08:19,640 --> 00:08:21,080
"and give me the result."

153
00:08:21,720 --> 00:08:24,360
The result will be
the new value of the counter.

154
00:08:24,520 --> 00:08:27,280
Then, when we've finished
here, we're going to say,

155
00:08:27,440 --> 00:08:29,800
"count", so the value of the counter,

156
00:08:29,960 --> 00:08:33,560
"Take this new value entered
by the user in the form of a Number".

157
00:08:34,520 --> 00:08:35,480
Quite simply.

158
00:08:35,920 --> 00:08:38,200
So internally,
we can examine the workings

159
00:08:38,400 --> 00:08:40,560
of this WAInputDialog box.

160
00:08:40,720 --> 00:08:44,760
It's a reusable Seaside component,
totally classic,

161
00:08:44,920 --> 00:08:47,000
except for one special feature,

162
00:08:47,160 --> 00:08:51,320
it uses the "answer" method
to send back a result.

163
00:08:52,080 --> 00:08:55,000
If we look at the
"renderContentOn" method

164
00:08:55,160 --> 00:08:56,720
of this component,

165
00:08:56,880 --> 00:08:59,720
when we click on its OK button,

166
00:08:59,880 --> 00:09:02,040
here, it's the "submit" button,

167
00:09:02,200 --> 00:09:06,280
it has a callback with a block,
and in its callback

168
00:09:06,960 --> 00:09:10,560
it will do "self answer: value".

169
00:09:11,040 --> 00:09:15,120
Which means that this
will send the result

170
00:09:15,280 --> 00:09:18,520
to the component that called it.

171
00:09:18,680 --> 00:09:22,440
It will really return to the place
from which the call was made

172
00:09:22,600 --> 00:09:24,520
and send the result.

173
00:09:25,760 --> 00:09:27,400
We've seen the call/answer mechanism.

174
00:09:27,560 --> 00:09:30,440
Now we'll see one last
component composition mechanism,

175
00:09:30,600 --> 00:09:33,120
the "Task" mechanism.

176
00:09:33,960 --> 00:09:35,160
It's actually very simple.

177
00:09:35,320 --> 00:09:37,880
Tasks are like components,
but there are no UI parts,

178
00:09:38,040 --> 00:09:41,320
so no "renderContentOn",
no generation of htmls.

179
00:09:41,480 --> 00:09:44,000
The idea is really to orchestrate,

180
00:09:44,160 --> 00:09:48,640
to describe how the components
should perform over time.

181
00:09:48,800 --> 00:09:51,480
This component will do this first,
then that one, etc...

182
00:09:51,640 --> 00:09:55,960
Using "call: answer" behind the scenes.

183
00:09:56,120 --> 00:09:58,920
So we'll define a task
called an "Adder"

184
00:09:59,080 --> 00:10:02,120
and then all the tasks
have a method called "go".

185
00:10:02,280 --> 00:10:04,680
Here, for example, in this task,

186
00:10:04,840 --> 00:10:09,800
we'll ask the user to enter a number,
so "self request: firstnumber"

187
00:10:09,960 --> 00:10:13,360
then we'll ask him to enter
a 2nd number, "Number 2"

188
00:10:13,520 --> 00:10:17,160
then we'll inform him of a value

189
00:10:17,320 --> 00:10:21,120
which is the sum
of these 2 numbers, here, OK?

190
00:10:21,280 --> 00:10:25,240
On the last line, we'll register
this component as an application...

191
00:10:25,400 --> 00:10:28,240
a classic Web application
to access it with a browser.

192
00:10:29,920 --> 00:10:31,560
So if we look inside it,

193
00:10:31,720 --> 00:10:34,680
how is the request method implemented?

194
00:10:34,840 --> 00:10:36,360
The request method is a string.

195
00:10:36,520 --> 00:10:41,600
Internally, as we can see,
it uses "call" and "answer".

196
00:10:41,800 --> 00:10:44,040
If we go back to the previous example,

197
00:10:44,200 --> 00:10:47,640
we see that when we made
the request here, internally,

198
00:10:47,800 --> 00:10:50,120
it called another component,

199
00:10:50,280 --> 00:10:54,520
and not just any old one,
the WAInputDialog component,

200
00:10:54,680 --> 00:10:56,560
it displayed the string,

201
00:10:56,720 --> 00:10:59,920
and this component will return
the result to whoever requested it.

202
00:11:00,080 --> 00:11:03,440
In this instance, who requested it?
Our component "Adder".

203
00:11:03,600 --> 00:11:06,440
So it will recuperate
a value in "Value 1".

204
00:11:06,600 --> 00:11:09,960
The same thing for "Value 2"
and then in "inform".

205
00:11:10,120 --> 00:11:13,440
If we take a look
at how "inform" is implemented,

206
00:11:13,600 --> 00:11:17,160
it also uses a call/answer,
but on another type of component,

207
00:11:17,320 --> 00:11:19,680
which is a "FormDialog".

208
00:11:19,840 --> 00:11:22,360
If we do "self, call: FormDialog"

209
00:11:22,520 --> 00:11:25,760
we'll display the string
with an OK button to say,

210
00:11:25,920 --> 00:11:28,040
"OK, he's seen the string".

211
00:11:28,800 --> 00:11:31,040
So what you need to know

212
00:11:31,240 --> 00:11:33,120
in all these forms of composition,

213
00:11:33,280 --> 00:11:36,080
we've never talked about requests,

214
00:11:36,240 --> 00:11:39,880
about http requests, about URL,
parsing and settings,

215
00:11:40,040 --> 00:11:42,880
we haven't talked about request routing.

216
00:11:43,040 --> 00:11:46,680
We haven't made any links
to the following pages, etc...

217
00:11:46,840 --> 00:11:50,160
We've only talked about components,

218
00:11:50,320 --> 00:11:52,640
stateful components
that we can compose,

219
00:11:52,800 --> 00:11:55,000
so the 3 forms of composition.

220
00:11:55,160 --> 00:11:57,120
A component can encapsulate others,

221
00:11:57,280 --> 00:11:59,480
a component can call another component,

222
00:11:59,640 --> 00:12:03,480
and we can define workflows,
strings of components in Seaside,

223
00:12:03,640 --> 00:12:04,920
which is extremely powerful,

224
00:12:05,080 --> 00:12:07,840
and all with the possibility
of live debugging.