Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
1
00:00:01,340 --> 00:00:04,840
So let's now learn how we can listen for events
2
2
00:00:04,840 --> 00:00:09,140
and also handle events in our MVC architecture
3
3
00:00:09,140 --> 00:00:13,083
by using something called the Publisher-Subscriber pattern.
4
4
00:00:15,130 --> 00:00:17,480
And let's start by analyzing the code
5
5
00:00:17,480 --> 00:00:18,993
that we already have here.
6
6
00:00:20,060 --> 00:00:22,800
So right now we are listening for the hashchange
7
7
00:00:24,070 --> 00:00:28,270
and for the load events right here in the controller.
8
8
00:00:28,270 --> 00:00:32,150
However, that doesn't make a lot of sense, does it?
9
9
00:00:32,150 --> 00:00:35,610
Because everything that is related to the DOM,
10
10
00:00:35,610 --> 00:00:40,270
so to the view, should really be inside of a view.
11
11
00:00:40,270 --> 00:00:43,840
Now, maybe these two events here don't really look
12
12
00:00:43,840 --> 00:00:47,090
as if they have to do with the view,
13
13
00:00:47,090 --> 00:00:49,150
so with the user interface.
14
14
00:00:49,150 --> 00:00:52,700
But imagine that instead we would be handling a click event
15
15
00:00:52,700 --> 00:00:55,150
on some DOM element.
16
16
00:00:55,150 --> 00:00:58,840
And so listening for that event should for sure,
17
17
00:00:58,840 --> 00:01:00,650
go into the view.
18
18
00:01:00,650 --> 00:01:04,830
And therefore, we can say the same about these events here.
19
19
00:01:04,830 --> 00:01:08,720
So in the end, this has more to do with DOM manipulation
20
20
00:01:08,720 --> 00:01:12,790
or what to DOM itself then actually with the controller.
21
21
00:01:12,790 --> 00:01:16,700
And so therefore, we need a way of putting this logic here
22
22
00:01:16,700 --> 00:01:19,880
into a recipe view.
23
23
00:01:19,880 --> 00:01:23,100
However, the handler function that we use
24
24
00:01:23,100 --> 00:01:26,363
to handle these events is actually this controller.
25
25
00:01:27,636 --> 00:01:29,590
So it's this function that we have up here
26
26
00:01:29,590 --> 00:01:33,060
that is sitting inside of this controller module.
27
27
00:01:33,060 --> 00:01:37,130
And so we have basically a problem here.
28
28
00:01:37,130 --> 00:01:39,890
We don't want this code to be here
29
29
00:01:39,890 --> 00:01:42,360
so we want it to be in the view.
30
30
00:01:42,360 --> 00:01:45,810
But in this code, we need this controller function
31
31
00:01:45,810 --> 00:01:47,930
which is here in this module.
32
32
00:01:47,930 --> 00:01:49,440
And of course, we don't want
33
33
00:01:49,440 --> 00:01:51,910
to put this function in the view.
34
34
00:01:51,910 --> 00:01:53,550
And so let's now think about
35
35
00:01:53,550 --> 00:01:55,323
how we could solve this problem.
36
36
00:01:57,330 --> 00:02:00,700
And recapping everything that I just said before,
37
37
00:02:00,700 --> 00:02:03,810
we can basically say that we want to handle events
38
38
00:02:03,810 --> 00:02:06,630
in the controller because otherwise,
39
39
00:02:06,630 --> 00:02:09,840
we would have application logic in the view,
40
40
00:02:09,840 --> 00:02:12,170
and of course we don't want that.
41
41
00:02:12,170 --> 00:02:13,550
But on the other hand,
42
42
00:02:13,550 --> 00:02:16,460
we want to listen for events in the view,
43
43
00:02:16,460 --> 00:02:19,500
because otherwise we would need DOM elements
44
44
00:02:19,500 --> 00:02:20,940
in the controller,
45
45
00:02:20,940 --> 00:02:23,820
and we would basically have presentation logic
46
46
00:02:23,820 --> 00:02:26,500
in the a controller which would be wrong
47
47
00:02:26,500 --> 00:02:29,120
in our MVC implementation.
48
48
00:02:29,120 --> 00:02:32,630
So essentially, event listeners should be attached
49
49
00:02:32,630 --> 00:02:34,810
to DOM elements in the view,
50
50
00:02:34,810 --> 00:02:37,170
but the events should then be handled
51
51
00:02:37,170 --> 00:02:41,700
by controller functions that live in the controller module.
52
52
00:02:41,700 --> 00:02:45,440
And so if you take a look at this small diagram
53
53
00:02:45,440 --> 00:02:48,720
that is just a part of the architecture diagram
54
54
00:02:48,720 --> 00:02:50,313
that we already saw before,
55
55
00:02:51,748 --> 00:02:53,230
so here we have to controlRecipes function
56
56
00:02:53,230 --> 00:02:54,520
in the controller,
57
57
00:02:54,520 --> 00:02:57,470
and we have a special method in the view,
58
58
00:02:57,470 --> 00:03:00,460
which is called addHandlerRender.
59
59
00:03:00,460 --> 00:03:04,360
Now, we might think that it is very easy to connect
60
60
00:03:04,360 --> 00:03:06,290
these two functions
61
61
00:03:06,290 --> 00:03:10,730
because why not simply call the control recipe's function
62
62
00:03:10,730 --> 00:03:14,670
right from the view whenever an event occurs?
63
63
00:03:14,670 --> 00:03:17,330
Well, that's actually not possible
64
64
00:03:17,330 --> 00:03:20,240
because in a way we set up the architecture,
65
65
00:03:20,240 --> 00:03:24,200
the view does not know anything about the controller.
66
66
00:03:24,200 --> 00:03:26,760
So it doesn't import the controller,
67
67
00:03:26,760 --> 00:03:29,230
and so we can't call any of the functions
68
68
00:03:29,230 --> 00:03:32,090
that are in the controller from the view.
69
69
00:03:32,090 --> 00:03:34,310
So it only works the other way around
70
70
00:03:34,310 --> 00:03:37,970
and therefore it's more complex than this.
71
71
00:03:37,970 --> 00:03:42,270
But fortunately, there is a good solution and this solution
72
72
00:03:42,270 --> 00:03:46,420
is called the Publisher-Subscriber Design pattern.
73
73
00:03:46,420 --> 00:03:50,080
And by the way, design patterns in programming
74
74
00:03:50,080 --> 00:03:52,650
are basically just standard solutions
75
75
00:03:52,650 --> 00:03:55,440
to certain kinds of problems.
76
76
00:03:55,440 --> 00:04:00,190
So in the publisher-Subscriber pattern we have a publisher
77
77
00:04:00,190 --> 00:04:04,470
which is some code that knows when to react.
78
78
00:04:04,470 --> 00:04:05,530
And in this case,
79
79
00:04:05,530 --> 00:04:08,530
that's going to be the addHandlerRender function
80
80
00:04:08,530 --> 00:04:12,390
because it will contain the addEventListener method.
81
81
00:04:12,390 --> 00:04:17,020
And therefore, it will know when to react to the event.
82
82
00:04:17,020 --> 00:04:20,460
Now, on the other hand, we have a subscriber
83
83
00:04:20,460 --> 00:04:24,320
which is code that actually wants to react.
84
84
00:04:24,320 --> 00:04:27,750
So this is the code that should actually be executed
85
85
00:04:27,750 --> 00:04:29,950
when the event happens.
86
86
00:04:29,950 --> 00:04:33,490
And in this case, that is the controlRecipes function
87
87
00:04:33,490 --> 00:04:36,510
that we already have in our controller.
88
88
00:04:36,510 --> 00:04:40,520
And remember that the publisher does not know yet
89
89
00:04:40,520 --> 00:04:42,930
that the subscriber even exists
90
90
00:04:42,930 --> 00:04:46,070
because that subscriber is in the controller
91
91
00:04:46,070 --> 00:04:48,690
that the view cannot access.
92
92
00:04:48,690 --> 00:04:49,523
Okay.
93
93
00:04:49,523 --> 00:04:53,700
But now finally comes to solution to the problem.
94
94
00:04:53,700 --> 00:04:57,080
So the solution is that we can now subscribe
95
95
00:04:57,080 --> 00:05:01,010
to the publisher by passing into subscriber function
96
96
00:05:01,010 --> 00:05:03,070
as an argument.
97
97
00:05:03,070 --> 00:05:05,290
Now in practice, that means that
98
98
00:05:05,290 --> 00:05:09,870
as soon as the program loads, the init function is called
99
99
00:05:09,870 --> 00:05:11,820
which in turn immediately calls
100
100
00:05:11,820 --> 00:05:15,430
the addHandlerRender function from the view.
101
101
00:05:15,430 --> 00:05:19,340
And that is possible, remember, because the controller
102
102
00:05:20,211 --> 00:05:23,653
does in fact import both the view and the model, right?
103
103
00:05:24,650 --> 00:05:28,120
Now, anyway, as we call addHendlerRender,
104
104
00:05:28,120 --> 00:05:33,120
we pass in our controlRecipes function as an argument.
105
105
00:05:33,300 --> 00:05:37,330
So essentially, we subscribe controlRecipes
106
106
00:05:37,330 --> 00:05:39,460
to addHandlerRender.
107
107
00:05:39,460 --> 00:05:42,170
And so at this point, the two functions
108
108
00:05:42,170 --> 00:05:45,330
are basically finally connected.
109
109
00:05:45,330 --> 00:05:49,580
And so now addHandlerRender listens for events
110
110
00:05:49,580 --> 00:05:53,456
using the addEventListener method as always.
111
111
00:05:53,456 --> 00:05:57,323
And then as soon as the event actually happens,
112
112
00:05:57,323 --> 00:05:59,570
the controlRecipes function will be called
113
113
00:05:59,570 --> 00:06:03,550
as the callback function of addEventListener.
114
114
00:06:03,550 --> 00:06:05,260
Or, in other words,
115
115
00:06:05,260 --> 00:06:08,650
as soon as the publisher publishes an event
116
116
00:06:08,650 --> 00:06:10,933
the subscriber will get called.
117
117
00:06:11,790 --> 00:06:12,660
All right.
118
118
00:06:12,660 --> 00:06:15,770
And this is how we implement event listeners
119
119
00:06:15,770 --> 00:06:19,860
and event handlers in the MVC architecture.
120
120
00:06:19,860 --> 00:06:23,530
So this will allow us to keep the handler in the controller
121
121
00:06:23,530 --> 00:06:25,620
and to listener in the view.
122
122
00:06:25,620 --> 00:06:30,030
And by that, keeping everything nicely separated.
123
123
00:06:30,030 --> 00:06:34,060
So in summary, the handler subscribes to the publisher,
124
124
00:06:34,060 --> 00:06:36,300
which is the listener in this case,
125
125
00:06:36,300 --> 00:06:39,830
and then as the publisher publishes an event,
126
126
00:06:39,830 --> 00:06:42,093
the subscriber is executed.
127
127
00:06:42,930 --> 00:06:45,790
And if you want to think even deeper about this
128
128
00:06:45,790 --> 00:06:47,890
and are really interested in this,
129
129
00:06:47,890 --> 00:06:51,780
then notice how there is actually a profound difference
130
130
00:06:51,780 --> 00:06:55,550
between a certain arbitrary like function A
131
131
00:06:55,550 --> 00:06:58,600
simply calling function B directly
132
132
00:06:58,600 --> 00:07:02,840
and function A receiving function B as an input
133
133
00:07:02,840 --> 00:07:06,160
in order to then call that input function.
134
134
00:07:06,160 --> 00:07:08,920
So this is all about control.
135
135
00:07:08,920 --> 00:07:12,780
In the first scenario, function A is in control.
136
136
00:07:12,780 --> 00:07:17,440
However, in the second scenario function A has no control.
137
137
00:07:17,440 --> 00:07:22,330
So it simply has to execute whatever function it receives.
138
138
00:07:22,330 --> 00:07:25,490
So if you want, reflect a little bit on that
139
139
00:07:25,490 --> 00:07:27,710
and see that this is exactly
140
140
00:07:27,710 --> 00:07:32,490
what the Publisher-Subscriber pattern is actually all about.
141
141
00:07:32,490 --> 00:07:36,310
But anyway, leaving that theory aside now,
142
142
00:07:36,310 --> 00:07:39,913
let's go back to our code and implement all of this.
143
143
00:07:41,490 --> 00:07:43,690
And so with everything we just learned
144
144
00:07:43,690 --> 00:07:46,690
about the Publisher-Subscriber pattern,
145
145
00:07:46,690 --> 00:07:48,550
actually, now implementing it
146
146
00:07:48,550 --> 00:07:51,423
should be the easiest part, right?
147
147
00:07:52,540 --> 00:07:55,153
So let's simply grab this code.
148
148
00:07:56,260 --> 00:07:57,750
So cutting it actually
149
149
00:07:58,940 --> 00:08:02,370
and then here we will create a new method
150
150
00:08:03,430 --> 00:08:07,440
and let's just put it somewhere, let's say here.
151
151
00:08:07,440 --> 00:08:09,983
And so this will be our addHandlerRender method
152
152
00:08:13,890 --> 00:08:15,333
that we just talked about.
153
153
00:08:17,070 --> 00:08:21,480
So addHandlerRender because this is going to be
154
154
00:08:21,480 --> 00:08:26,250
for rendering the recipe right at the beginning, right?
155
155
00:08:26,250 --> 00:08:30,490
And then this method, which remember, is the publisher
156
156
00:08:30,490 --> 00:08:34,000
basically needs to get access to the subscriber.
157
157
00:08:34,000 --> 00:08:36,673
And so that in this case is the handler function.
158
158
00:08:40,230 --> 00:08:41,063
All right?
159
159
00:08:42,363 --> 00:08:45,530
And so then we can simply paste that in here.
160
160
00:08:45,530 --> 00:08:49,470
And then here, of course we don't know about controlRecipes,
161
161
00:08:49,470 --> 00:08:51,103
but we know about the handler.
162
162
00:08:52,950 --> 00:08:56,630
And so that's actually it for this function.
163
163
00:08:56,630 --> 00:08:59,370
So of course it is not a private method
164
164
00:08:59,370 --> 00:09:03,990
because it needs to be part of the public API of this object
165
165
00:09:03,990 --> 00:09:07,780
so that we can then call it in the controller, right.
166
166
00:09:07,780 --> 00:09:10,343
And so let's actually do that now.
167
167
00:09:11,520 --> 00:09:13,670
So we can get rid of this now.
168
168
00:09:13,670 --> 00:09:16,480
And we will want to do this right in the beginning.
169
169
00:09:16,480 --> 00:09:18,573
So let's create an init function here,
170
170
00:09:20,520 --> 00:09:22,283
actually like this,
171
171
00:09:25,843 --> 00:09:28,270
and then we simply call it right at the beginning.
172
172
00:09:28,270 --> 00:09:29,990
So only once.
173
173
00:09:29,990 --> 00:09:32,560
And actually we could simply put all the code
174
174
00:09:32,560 --> 00:09:34,710
also here in the global scope,
175
175
00:09:34,710 --> 00:09:36,560
but I think it's a bit cleaner
176
176
00:09:36,560 --> 00:09:38,913
to have a separate function for this.
177
177
00:09:39,770 --> 00:09:44,723
That's recipeView.addHandlerRender.
178
178
00:09:45,780 --> 00:09:49,783
And so now we simply pass in controlRecipes,
179
179
00:09:51,481 --> 00:09:53,424
and that's actually it.
180
180
00:09:53,424 --> 00:09:54,460
With this, we just implemented
181
181
00:09:54,460 --> 00:09:57,220
the Publisher-Subscriber pattern.
182
182
00:09:57,220 --> 00:10:00,700
For some reason, we're still getting these errors here.
183
183
00:10:00,700 --> 00:10:03,140
Let's get rid of this alert here actually,
184
184
00:10:03,140 --> 00:10:05,283
and simply do a console.log here.
185
185
00:10:08,900 --> 00:10:09,810
Okay.
186
186
00:10:09,810 --> 00:10:13,033
But now let's go and see if this actually works.
187
187
00:10:15,690 --> 00:10:17,653
We're still having our slow network.
188
188
00:10:22,910 --> 00:10:26,430
Oh, and here we have some problem apparently
189
189
00:10:26,430 --> 00:10:28,220
with the timeout.
190
190
00:10:28,220 --> 00:10:31,933
So let's go quickly fix that here in the helpers.
191
191
00:10:32,940 --> 00:10:37,590
So we saw that here it said undefined,
192
192
00:10:37,590 --> 00:10:39,930
like after undefined second.
193
193
00:10:39,930 --> 00:10:43,200
So maybe this variable here doesn't exist.
194
194
00:10:43,200 --> 00:10:46,600
So maybe it's misspelled.
195
195
00:10:46,600 --> 00:10:47,950
So let's see in the config.
196
196
00:10:50,206 --> 00:10:51,256
Well, it looks right.
197
197
00:10:55,570 --> 00:10:57,053
Yeah, it is the same.
198
198
00:10:58,710 --> 00:11:00,433
Well, let's see again.
199
199
00:11:01,980 --> 00:11:05,190
And so this apparently happens immediately
200
200
00:11:05,190 --> 00:11:06,240
for some reason here.
201
201
00:11:10,300 --> 00:11:14,053
So what if we put it back to some normal number?
202
202
00:11:15,210 --> 00:11:18,990
Well, then it works, which is very weird
203
203
00:11:20,160 --> 00:11:22,983
because this is in fact also 10.
204
204
00:11:25,830 --> 00:11:29,773
So let's see what we get here as we lock timeout seconds.
205
205
00:11:32,010 --> 00:11:35,640
Oh, I'm actually right now seeing the problem.
206
206
00:11:35,640 --> 00:11:38,860
So this is not helpers, it is config.
207
207
00:11:38,860 --> 00:11:40,773
So we are importing ourselves here.
208
208
00:11:42,400 --> 00:11:44,023
So that was the problem.
209
209
00:11:47,390 --> 00:11:48,863
Let's put everything back.
210
210
00:11:50,110 --> 00:11:52,423
And you see that now it is working.
211
211
00:11:53,570 --> 00:11:55,913
Even with the hashchange event.
212
212
00:11:57,790 --> 00:12:01,690
And so that means that we did now successfully implement
213
213
00:12:01,690 --> 00:12:04,800
the Publisher-Subscriber pattern.
214
214
00:12:04,800 --> 00:12:05,710
Okay?
215
215
00:12:05,710 --> 00:12:10,263
And so let's quickly recap what exactly is happening here.
216
216
00:12:11,970 --> 00:12:15,523
So we can also take a look at our final diagram here.
217
217
00:12:16,690 --> 00:12:20,760
And here, I actually have the event here in the controller
218
218
00:12:20,760 --> 00:12:23,940
because that is actually where it is handled.
219
219
00:12:23,940 --> 00:12:26,220
And so I think that in this diagram,
220
220
00:12:26,220 --> 00:12:28,150
this makes it a little bit easier
221
221
00:12:28,150 --> 00:12:31,540
to actually understand the flow of the program.
222
222
00:12:31,540 --> 00:12:35,720
So anyway, as we start to program
223
223
00:12:35,720 --> 00:12:38,490
then the init function runs
224
224
00:12:38,490 --> 00:12:43,170
and it will then immediately run addHandlerRender, right?
225
225
00:12:43,170 --> 00:12:45,760
So it is this function here.
226
226
00:12:45,760 --> 00:12:47,750
And it's this function that is actually
227
227
00:12:47,750 --> 00:12:50,950
listening for events right here in the view
228
228
00:12:50,950 --> 00:12:53,130
where it actually makes sense.
229
229
00:12:53,130 --> 00:12:57,480
Now, as we call this method here, so in the controller,
230
230
00:12:57,480 --> 00:13:01,610
we pass in the controller function or the handler function
231
231
00:13:01,610 --> 00:13:05,950
that we want to get executed as soon as the event happens,
232
232
00:13:05,950 --> 00:13:06,783
right?
233
233
00:13:06,783 --> 00:13:09,430
And here we then receive that function
234
234
00:13:09,430 --> 00:13:11,430
as being called handler.
235
235
00:13:11,430 --> 00:13:13,540
And so that's what we then call
236
236
00:13:13,540 --> 00:13:16,940
as soon as the event happens, right?
237
237
00:13:16,940 --> 00:13:18,620
And so again in our diagram,
238
238
00:13:18,620 --> 00:13:20,563
that's exactly what we have here.
239
239
00:13:21,910 --> 00:13:24,440
So that's why I have this dotted line here
240
240
00:13:24,440 --> 00:13:26,310
which stands for data flow.
241
241
00:13:26,310 --> 00:13:29,490
So we are passing in the controlRecipe function
242
242
00:13:29,490 --> 00:13:31,780
as the handler here.
243
243
00:13:31,780 --> 00:13:33,320
And that is the whole reason
244
244
00:13:33,320 --> 00:13:37,520
why the method here is called addHandlerRender.
245
245
00:13:37,520 --> 00:13:40,430
So because we are using it to, in fact,
246
246
00:13:40,430 --> 00:13:43,140
add a handler function and in this case,
247
247
00:13:43,140 --> 00:13:46,530
it is for rendering the recipe in the first place.
248
248
00:13:46,530 --> 00:13:47,630
And then later on,
249
249
00:13:47,630 --> 00:13:51,263
we will actually have other addHandler methods.
250
250
00:13:52,200 --> 00:13:53,033
Okay?
251
251
00:13:53,033 --> 00:13:57,030
And so it's crucial that you understand this logic here
252
252
00:13:57,030 --> 00:14:01,000
before you can move on any further in this project.
253
253
00:14:01,000 --> 00:14:03,670
But I hope that with all this explanation,
254
254
00:14:03,670 --> 00:14:05,530
this became all really clear
255
255
00:14:05,530 --> 00:14:09,200
and also obvious why we had to do it like this.
256
256
00:14:09,200 --> 00:14:12,440
I mean, of course we don't really have to do it,
257
257
00:14:12,440 --> 00:14:15,470
so we are, of course, in charge of our own code.
258
258
00:14:15,470 --> 00:14:19,690
But in order to correctly implement the MVC architecture,
259
259
00:14:19,690 --> 00:14:22,110
this is the best way of doing it.
260
260
00:14:22,110 --> 00:14:26,330
And so again, then we can keep everything nicely separated
261
261
00:14:26,330 --> 00:14:30,070
into a model controller and view
262
262
00:14:30,070 --> 00:14:33,880
without any overlapping responsibilities.
263
263
00:14:33,880 --> 00:14:34,960
All right.
264
264
00:14:34,960 --> 00:14:39,160
So we have all of this structure here now nicely set up,
265
265
00:14:39,160 --> 00:14:41,280
everything is nicely separated.
266
266
00:14:41,280 --> 00:14:43,920
And so from now on, all we have to do
267
267
00:14:43,920 --> 00:14:47,150
is to basically use this structure to implement
268
268
00:14:47,150 --> 00:14:50,390
all of the missing features off our application.
269
269
00:14:50,390 --> 00:14:53,850
And so again, really make sure that you understand
270
270
00:14:53,850 --> 00:14:56,070
everything that we did so far,
271
271
00:14:56,070 --> 00:15:00,560
especially regarding the implementation of our architecture.
272
272
00:15:00,560 --> 00:15:04,000
And then once you are really done with understanding that,
273
273
00:15:04,000 --> 00:15:06,373
let's go straight to the next video.
23983
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.