WEBVTT

00:00:07.640 --> 00:00:11.920 align:middle
Hello, in this sequence,
you'll see the power of Seaside,

00:00:12.080 --> 00:00:14.480 align:middle
through the composition of components.

00:00:14.640 --> 00:00:18.360 align:middle
We defined the reusable
and stateful components,

00:00:18.520 --> 00:00:21.760 align:middle
now we'll see how we can
put these components together

00:00:21.920 --> 00:00:25.200 align:middle
in order to build complex applications.
As we said, an application

00:00:25.360 --> 00:00:27.120 align:middle
is a root component,

00:00:27.280 --> 00:00:31.760 align:middle
so we benefit from debugging,
of live debugging of applications.

00:00:31.920 --> 00:00:35.240 align:middle
We'll go back over
3 important mechanisms

00:00:35.400 --> 00:00:37.480 align:middle
for composing components in Seaside.

00:00:37.640 --> 00:00:40.080 align:middle
The first is component aggregation.

00:00:40.240 --> 00:00:42.880 align:middle
Remember, we defined 2 counters,

00:00:43.040 --> 00:00:46.000 align:middle
one normal counter,
which looked like this

00:00:46.160 --> 00:00:49.800 align:middle
and a Twitter counter, here.

00:00:49.960 --> 00:00:51.000 align:middle
OK?

00:00:51.160 --> 00:00:56.080 align:middle
How can I now aggregate
a component counter

00:00:56.280 --> 00:00:58.280 align:middle
with a view to building
a multi-counter application?

00:00:58.440 --> 00:01:00.720 align:middle
I want to show lots
of counters on one page.

00:01:00.880 --> 00:01:03.360 align:middle
When I click on this +, for example,

00:01:03.520 --> 00:01:06.680 align:middle
it only increases the value
of this particular counter, OK?

00:01:06.840 --> 00:01:11.080 align:middle
So, aggregating lots of components
on the same page, easily.

00:01:11.240 --> 00:01:13.800 align:middle
So how do we do this in Seaside?
It's extremely simple.

00:01:13.960 --> 00:01:17.400 align:middle
I'll define a component subclass,
which is always the same,

00:01:17.560 --> 00:01:19.720 align:middle
which is called "WAMultiCounter",

00:01:19.880 --> 00:01:23.080 align:middle
"instance variable counters",
defining a collection of counters.

00:01:23.240 --> 00:01:28.480 align:middle
In "method initialize" I'll create
a collection of 5 counters, here.

00:01:29.520 --> 00:01:30.440 align:middle
OK?

00:01:30.600 --> 00:01:34.840 align:middle
And then I'll have the method
"rendercontentOn", here

00:01:35.000 --> 00:01:38.920 align:middle
where I'll say I'll browse
my counter collection with a "do"

00:01:39.080 --> 00:01:42.400 align:middle
and I'll ask each counter,
at least, the html object,

00:01:42.560 --> 00:01:47.000 align:middle
to render each of the counters.
I use a special method, "render".

00:01:47.160 --> 00:01:50.680 align:middle
This render method of the html object

00:01:50.840 --> 00:01:55.560 align:middle
allows you to ask a component
to render itself, draw itself in html.

00:01:55.720 --> 00:01:58.640 align:middle
We've an important method here
called "children",

00:01:58.800 --> 00:02:02.640 align:middle
which means that when a component
encapsulates other components

00:02:02.800 --> 00:02:05.560 align:middle
and asks them to render
in "renderContentOn",

00:02:05.720 --> 00:02:09.800 align:middle
it has to declare them, and to do that
it has to render a collection

00:02:09.960 --> 00:02:11.760 align:middle
of components in its method "children"

00:02:11.920 --> 00:02:15.440 align:middle
which contains all the components
it's going to render, all its children.

00:02:15.600 --> 00:02:18.800 align:middle
Here I'm rendering
the collection "counters".

00:02:18.960 --> 00:02:21.680 align:middle
It's an important method to define.

00:02:22.600 --> 00:02:25.560 align:middle
So, the basic rules
for aggregating components,

00:02:25.720 --> 00:02:27.840 align:middle
composing components is easy.

00:02:28.000 --> 00:02:30.920 align:middle
One component
will store its subcomponents

00:02:31.080 --> 00:02:35.680 align:middle
in an instance variable.
In our example it's "counters", OK?

00:02:35.840 --> 00:02:38.440 align:middle
It will then pass the "render" message

00:02:38.600 --> 00:02:41.760 align:middle
to html,

00:02:41.920 --> 00:02:46.600 align:middle
in its "renderContentOn" method,
asking each child to render itself.

00:02:47.480 --> 00:02:49.440 align:middle
It will then redefine
the method "children"

00:02:49.600 --> 00:02:52.000 align:middle
to declare all of its subcomponents.

00:02:53.080 --> 00:02:54.480 align:middle
There are always these 3 parts.

00:02:57.240 --> 00:03:00.000 align:middle
We can also aggregate
different subcomponents.

00:03:00.160 --> 00:03:02.280 align:middle
They don't have to be the same type.

00:03:02.440 --> 00:03:06.800 align:middle
Before, I only combined counters
and here we're going to have

00:03:06.960 --> 00:03:09.920 align:middle
an application, a MyApp component.

00:03:10.080 --> 00:03:12.520 align:middle
In the method "initialize"
it's a collection,

00:03:12.680 --> 00:03:15.320 align:middle
except that in this collection I put

00:03:15.480 --> 00:03:19.200 align:middle
the app "Greeter" that we used
in a previous sequence, which we saw,

00:03:19.360 --> 00:03:22.600 align:middle
a Tweeter counter and a counter.
3 components.

00:03:22.760 --> 00:03:25.680 align:middle
My method, "children" renders

00:03:25.840 --> 00:03:29.200 align:middle
all the children, the subcomponents
of this MyApp component,

00:03:29.360 --> 00:03:30.960 align:middle
and in "renderContentOn"

00:03:31.120 --> 00:03:35.560 align:middle
I want to browse my children
and ask them to render themselves.

00:03:35.720 --> 00:03:37.880 align:middle
So we do "html render: each"

00:03:38.040 --> 00:03:40.480 align:middle
and I'll do "html render" of Greeter,

00:03:40.640 --> 00:03:43.400 align:middle
the Twitter counter and counter.

00:03:43.560 --> 00:03:44.800 align:middle
Let's see what we get.

00:03:44.960 --> 00:03:49.880 align:middle
Here we have the Greeter component,
which is displayed on the Web page,

00:03:50.040 --> 00:03:52.840 align:middle
we've the Twitter counter
displayed here,

00:03:53.000 --> 00:03:55.240 align:middle
and the normal counter displayed here.

00:03:55.400 --> 00:03:58.640 align:middle
We've composed the components
and they all work independently

00:03:58.800 --> 00:04:00.960 align:middle
if I click on the +
and the "Say Hello" etc,

00:04:01.120 --> 00:04:02.840 align:middle
the components work perfectly.

00:04:04.880 --> 00:04:08.000 align:middle
So now, if you like,
there's one stage further.

00:04:08.160 --> 00:04:12.200 align:middle
We don't want all the components
at once on the Web page.

00:04:12.360 --> 00:04:15.720 align:middle
We want one at a time,
a menu, for example, to select

00:04:15.880 --> 00:04:17.560 align:middle
which subcomponent
we want displayed.

00:04:17.720 --> 00:04:19.840 align:middle
Typically,
I only want to show the Greeter

00:04:20.000 --> 00:04:22.120 align:middle
and when I click on Twitter counter here,

00:04:22.280 --> 00:04:26.120 align:middle
I'm only going to display
the Twitter counter.

00:04:26.280 --> 00:04:28.800 align:middle
How do we make this application?
It's easy.

00:04:28.960 --> 00:04:31.880 align:middle
I add an instance variable
in my MyApp application,

00:04:32.040 --> 00:04:35.440 align:middle
which is called the selected
component, the selected child.

00:04:35.600 --> 00:04:38.760 align:middle
By default, I'll initialize it

00:04:38.920 --> 00:04:40.960 align:middle
to the first subcomponent,

00:04:41.120 --> 00:04:44.280 align:middle
In the "renderContentOn" method,
here, I've modified it,

00:04:44.440 --> 00:04:46.640 align:middle
I'll display one menu,

00:04:46.800 --> 00:04:50.680 align:middle
giving me the possibility to select
which subcomponent I display,

00:04:50.840 --> 00:04:55.000 align:middle
then I do "html render" but only
of the subcomponent I want to display.

00:04:55.160 --> 00:04:56.520 align:middle
Quite simply.

00:04:56.680 --> 00:05:00.440 align:middle
In the menu, I'll generate
one unordered list,

00:05:00.600 --> 00:05:04.120 align:middle
I'll browse all of my subcomponents

00:05:04.280 --> 00:05:06.680 align:middle
which I browse with an index, "i"

00:05:08.160 --> 00:05:11.480 align:middle
and I generate a list element
for each child.

00:05:11.640 --> 00:05:13.680 align:middle
Here, I'm going to generate an anchor,

00:05:13.840 --> 00:05:17.480 align:middle
a clickable link,
and when I click on this link,

00:05:17.640 --> 00:05:22.600 align:middle
it will trigger the callback,
the execution of this block, here.

00:05:22.760 --> 00:05:27.600 align:middle
So we can say, it's easy,
the component selected by the user

00:05:27.760 --> 00:05:31.480 align:middle
is the child number...
so "self children".

00:05:31.640 --> 00:05:33.320 align:middle
Remember, it's a collection...

00:05:33.480 --> 00:05:35.000 align:middle
"at: i"

00:05:35.160 --> 00:05:38.200 align:middle
OK? And "i" here

00:05:38.360 --> 00:05:41.640 align:middle
is no more nor less
than the number of the element

00:05:41.800 --> 00:05:43.360 align:middle
in the "children" collection.

00:05:45.200 --> 00:05:49.680 align:middle
So it's extremely easy to be able
to browse all of the subcomponents

00:05:49.840 --> 00:05:52.320 align:middle
and to specifically generate,
to completely control

00:05:52.480 --> 00:05:54.600 align:middle
what should and shouldn't
be displayed.

00:05:56.080 --> 00:05:59.640 align:middle
We've a 2nd composition mechanism,
which is "call answer".

00:05:59.800 --> 00:06:02.080 align:middle
We've seen components aggregation

00:06:02.240 --> 00:06:05.800 align:middle
with subcomponents, and now we'll see
the "call answer" mechanism.

00:06:05.960 --> 00:06:09.960 align:middle
If we imagine,
in the code of component A,

00:06:10.120 --> 00:06:14.280 align:middle
we'll write something that looks
like this code here, we'll say,

00:06:15.040 --> 00:06:19.120 align:middle
component A calls component B.
Call component B.

00:06:19.280 --> 00:06:24.240 align:middle
What will happen is, component B
will mask component A on the Web page,

00:06:24.400 --> 00:06:26.120 align:middle
it will carry out a treatment,

00:06:26.280 --> 00:06:28.880 align:middle
and after a while, component B
will say, "I've done my treatment,

00:06:29.040 --> 00:06:31.200 align:middle
"I'll do answer and give a result".

00:06:31.360 --> 00:06:33.760 align:middle
Here the result is a star,

00:06:33.920 --> 00:06:36.440 align:middle
and this result will be stored in X

00:06:37.320 --> 00:06:40.080 align:middle
in the place of "call component B".

00:06:40.240 --> 00:06:43.280 align:middle
Now, component B will reappear
on the Web page

00:06:43.440 --> 00:06:46.080 align:middle
and component A can use this result
to do something.

00:06:46.720 --> 00:06:48.000 align:middle
I'll show you an example.

00:06:48.160 --> 00:06:51.760 align:middle
Here we have a component,
which was the counter.

00:06:51.920 --> 00:06:54.920 align:middle
We've added a button,
here, "Set Value",

00:06:55.080 --> 00:06:57.440 align:middle
We imagine that "Set Value"
allows the user

00:06:57.600 --> 00:06:59.560 align:middle
to enter a new value for the counter.

00:06:59.720 --> 00:07:03.440 align:middle
When we click on "Set Value"
a new component is displayed,

00:07:03.600 --> 00:07:07.000 align:middle
which allows us to enter,
a bit like the Greeter component,

00:07:07.160 --> 00:07:10.360 align:middle
we can enter a new value
for the counter, click on "OK"

00:07:10.520 --> 00:07:14.120 align:middle
and when I click on "OK"
it goes back to our counter component

00:07:14.280 --> 00:07:18.080 align:middle
but with the value entered here
by the user at the beginning.

00:07:18.280 --> 00:07:19.600 align:middle
OK?

00:07:19.760 --> 00:07:22.080 align:middle
So we've a series
of several components.

00:07:23.000 --> 00:07:24.640 align:middle
How is this implemented?

00:07:24.800 --> 00:07:29.200 align:middle
We've our Twitter counter
with its "renderContentOn" method.

00:07:29.360 --> 00:07:33.320 align:middle
To its "renderContentOn" method
we'll add a button,

00:07:33.480 --> 00:07:37.160 align:middle
a tbsButton, etc...
This button's called "Set Value", here.

00:07:37.320 --> 00:07:41.000 align:middle
When we click on this button,
this callback will be executed.

00:07:41.160 --> 00:07:43.960 align:middle
It's the "setCountToUserValue" method.

00:07:44.120 --> 00:07:46.600 align:middle
SetCountToUser is defined here.

00:07:46.760 --> 00:07:50.120 align:middle
What we do is we'll prepare
a dialogue box here.

00:07:50.280 --> 00:07:53.920 align:middle
We'll use another component
made by Seaside, a dialogue box.

00:07:54.080 --> 00:07:56.000 align:middle
which we'll configure here,

00:07:56.160 --> 00:07:59.320 align:middle
in this instance with
"Enter a new value for the counter".

00:07:59.480 --> 00:08:02.200 align:middle
The default setting is 0
and we've an OK button.

00:08:02.840 --> 00:08:04.320 align:middle
What we'll do next...

00:08:04.480 --> 00:08:07.080 align:middle
The really interesting
element is this line here...

00:08:07.840 --> 00:08:09.040 align:middle
Here...

00:08:10.200 --> 00:08:13.400 align:middle
We're going to say,
"current component", so "Self".

00:08:13.560 --> 00:08:15.800 align:middle
Remember,
"Self" is the Twitter counter.

00:08:15.960 --> 00:08:19.480 align:middle
"Call the dialogue box
we've just created,

00:08:19.640 --> 00:08:21.080 align:middle
"and give me the result."

00:08:21.720 --> 00:08:24.360 align:middle
The result will be
the new value of the counter.

00:08:24.520 --> 00:08:27.280 align:middle
Then, when we've finished
here, we're going to say,

00:08:27.440 --> 00:08:29.800 align:middle
"count", so the value of the counter,

00:08:29.960 --> 00:08:33.560 align:middle
"Take this new value entered
by the user in the form of a Number".

00:08:34.520 --> 00:08:35.480 align:middle
Quite simply.

00:08:35.920 --> 00:08:38.200 align:middle
So internally,
we can examine the workings

00:08:38.400 --> 00:08:40.560 align:middle
of this WAInputDialog box.

00:08:40.720 --> 00:08:44.760 align:middle
It's a reusable Seaside component,
totally classic,

00:08:44.920 --> 00:08:47.000 align:middle
except for one special feature,

00:08:47.160 --> 00:08:51.320 align:middle
it uses the "answer" method
to send back a result.

00:08:52.080 --> 00:08:55.000 align:middle
If we look at the
"renderContentOn" method

00:08:55.160 --> 00:08:56.720 align:middle
of this component,

00:08:56.880 --> 00:08:59.720 align:middle
when we click on its OK button,

00:08:59.880 --> 00:09:02.040 align:middle
here, it's the "submit" button,

00:09:02.200 --> 00:09:06.280 align:middle
it has a callback with a block,
and in its callback

00:09:06.960 --> 00:09:10.560 align:middle
it will do "self answer: value".

00:09:11.040 --> 00:09:15.120 align:middle
Which means that this
will send the result

00:09:15.280 --> 00:09:18.520 align:middle
to the component that called it.

00:09:18.680 --> 00:09:22.440 align:middle
It will really return to the place
from which the call was made

00:09:22.600 --> 00:09:24.520 align:middle
and send the result.

00:09:25.760 --> 00:09:27.400 align:middle
We've seen the call/answer mechanism.

00:09:27.560 --> 00:09:30.440 align:middle
Now we'll see one last
component composition mechanism,

00:09:30.600 --> 00:09:33.120 align:middle
the "Task" mechanism.

00:09:33.960 --> 00:09:35.160 align:middle
It's actually very simple.

00:09:35.320 --> 00:09:37.880 align:middle
Tasks are like components,
but there are no UI parts,

00:09:38.040 --> 00:09:41.320 align:middle
so no "renderContentOn",
no generation of htmls.

00:09:41.480 --> 00:09:44.000 align:middle
The idea is really to orchestrate,

00:09:44.160 --> 00:09:48.640 align:middle
to describe how the components
should perform over time.

00:09:48.800 --> 00:09:51.480 align:middle
This component will do this first,
then that one, etc...

00:09:51.640 --> 00:09:55.960 align:middle
Using "call: answer" behind the scenes.

00:09:56.120 --> 00:09:58.920 align:middle
So we'll define a task
called an "Adder"

00:09:59.080 --> 00:10:02.120 align:middle
and then all the tasks
have a method called "go".

00:10:02.280 --> 00:10:04.680 align:middle
Here, for example, in this task,

00:10:04.840 --> 00:10:09.800 align:middle
we'll ask the user to enter a number,
so "self request: firstnumber"

00:10:09.960 --> 00:10:13.360 align:middle
then we'll ask him to enter
a 2nd number, "Number 2"

00:10:13.520 --> 00:10:17.160 align:middle
then we'll inform him of a value

00:10:17.320 --> 00:10:21.120 align:middle
which is the sum
of these 2 numbers, here, OK?

00:10:21.280 --> 00:10:25.240 align:middle
On the last line, we'll register
this component as an application...

00:10:25.400 --> 00:10:28.240 align:middle
a classic Web application
to access it with a browser.

00:10:29.920 --> 00:10:31.560 align:middle
So if we look inside it,

00:10:31.720 --> 00:10:34.680 align:middle
how is the request method implemented?

00:10:34.840 --> 00:10:36.360 align:middle
The request method is a string.

00:10:36.520 --> 00:10:41.600 align:middle
Internally, as we can see,
it uses "call" and "answer".

00:10:41.800 --> 00:10:44.040 align:middle
If we go back to the previous example,

00:10:44.200 --> 00:10:47.640 align:middle
we see that when we made
the request here, internally,

00:10:47.800 --> 00:10:50.120 align:middle
it called another component,

00:10:50.280 --> 00:10:54.520 align:middle
and not just any old one,
the WAInputDialog component,

00:10:54.680 --> 00:10:56.560 align:middle
it displayed the string,

00:10:56.720 --> 00:10:59.920 align:middle
and this component will return
the result to whoever requested it.

00:11:00.080 --> 00:11:03.440 align:middle
In this instance, who requested it?
Our component "Adder".

00:11:03.600 --> 00:11:06.440 align:middle
So it will recuperate
a value in "Value 1".

00:11:06.600 --> 00:11:09.960 align:middle
The same thing for "Value 2"
and then in "inform".

00:11:10.120 --> 00:11:13.440 align:middle
If we take a look
at how "inform" is implemented,

00:11:13.600 --> 00:11:17.160 align:middle
it also uses a call/answer,
but on another type of component,

00:11:17.320 --> 00:11:19.680 align:middle
which is a "FormDialog".

00:11:19.840 --> 00:11:22.360 align:middle
If we do "self, call: FormDialog"

00:11:22.520 --> 00:11:25.760 align:middle
we'll display the string
with an OK button to say,

00:11:25.920 --> 00:11:28.040 align:middle
"OK, he's seen the string".

00:11:28.800 --> 00:11:31.040 align:middle
So what you need to know

00:11:31.240 --> 00:11:33.120 align:middle
in all these forms of composition,

00:11:33.280 --> 00:11:36.080 align:middle
we've never talked about requests,

00:11:36.240 --> 00:11:39.880 align:middle
about http requests, about URL,
parsing and settings,

00:11:40.040 --> 00:11:42.880 align:middle
we haven't talked about request routing.

00:11:43.040 --> 00:11:46.680 align:middle
We haven't made any links
to the following pages, etc...

00:11:46.840 --> 00:11:50.160 align:middle
We've only talked about components,

00:11:50.320 --> 00:11:52.640 align:middle
stateful components
that we can compose,

00:11:52.800 --> 00:11:55.000 align:middle
so the 3 forms of composition.

00:11:55.160 --> 00:11:57.120 align:middle
A component can encapsulate others,

00:11:57.280 --> 00:11:59.480 align:middle
a component can call another component,

00:11:59.640 --> 00:12:03.480 align:middle
and we can define workflows,
strings of components in Seaside,

00:12:03.640 --> 00:12:04.920 align:middle
which is extremely powerful,

00:12:05.080 --> 00:12:07.840 align:middle
and all with the possibility
of live debugging.

