Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
1 1
So let's now learn how we can listen for events 2
2
and also handle events in our MVC architecture 3
3
by using something called the Publisher-Subscriber pattern. 4
4
And let's start by analyzing the code 5
5
that we already have here. 6
6
So right now we are listening for the hashchange 7
7
and for the load events right here in the controller. 8
8
However, that doesn't make a lot of sense, does it? 9
9
Because everything that is related to the DOM, 10
10
so to the view, should really be inside of a view. 11
11
Now, maybe these two events here don't really look 12
12
as if they have to do with the view, 13
13
so with the user interface. 14
14
But imagine that instead we would be handling a click event 15
15
on some DOM element. 16
16
And so listening for that event should for sure, 17
17
go into the view. 18
18
And therefore, we can say the same about these events here. 19
19
So in the end, this has more to do with DOM manipulation 20
20
or what to DOM itself then actually with the controller. 21
21
And so therefore, we need a way of putting this logic here 22
22
into a recipe view. 23
23
However, the handler function that we use 24
24
to handle these events is actually this controller. 25
25
So it's this function that we have up here 26
26
that is sitting inside of this controller module. 27
27
And so we have basically a problem here. 28
28
We don't want this code to be here 29
29
so we want it to be in the view. 30
30
But in this code, we need this controller function 31
31
which is here in this module. 32
32
And of course, we don't want 33
33
to put this function in the view. 34
34
And so let's now think about 35
35
how we could solve this problem. 36
36
And recapping everything that I just said before, 37
37
we can basically say that we want to handle events 38
38
in the controller because otherwise, 39
39
we would have application logic in the view, 40
40
and of course we don't want that. 41
41
But on the other hand, 42
42
we want to listen for events in the view, 43
43
because otherwise we would need DOM elements 44
44
in the controller, 45
45
and we would basically have presentation logic 46
46
in the a controller which would be wrong 47
47
in our MVC implementation. 48
48
So essentially, event listeners should be attached 49
49
to DOM elements in the view, 50
50
but the events should then be handled 51
51
by controller functions that live in the controller module. 52
52
And so if you take a look at this small diagram 53
53
that is just a part of the architecture diagram 54
54
that we already saw before, 55
55
so here we have to controlRecipes function 56
56
in the controller, 57
57
and we have a special method in the view, 58
58
which is called addHandlerRender. 59
59
Now, we might think that it is very easy to connect 60
60
these two functions 61
61
because why not simply call the control recipe's function 62
62
right from the view whenever an event occurs? 63
63
Well, that's actually not possible 64
64
because in a way we set up the architecture, 65
65
the view does not know anything about the controller. 66
66
So it doesn't import the controller, 67
67
and so we can't call any of the functions 68
68
that are in the controller from the view. 69
69
So it only works the other way around 70
70
and therefore it's more complex than this. 71
71
But fortunately, there is a good solution and this solution 72
72
is called the Publisher-Subscriber Design pattern. 73
73
And by the way, design patterns in programming 74
74
are basically just standard solutions 75
75
to certain kinds of problems. 76
76
So in the publisher-Subscriber pattern we have a publisher 77
77
which is some code that knows when to react. 78
78
And in this case, 79
79
that's going to be the addHandlerRender function 80
80
because it will contain the addEventListener method. 81
81
And therefore, it will know when to react to the event. 82
82
Now, on the other hand, we have a subscriber 83
83
which is code that actually wants to react. 84
84
So this is the code that should actually be executed 85
85
when the event happens. 86
86
And in this case, that is the controlRecipes function 87
87
that we already have in our controller. 88
88
And remember that the publisher does not know yet 89
89
that the subscriber even exists 90
90
because that subscriber is in the controller 91
91
that the view cannot access. 92
92
Okay. 93
93
But now finally comes to solution to the problem. 94
94
So the solution is that we can now subscribe 95
95
to the publisher by passing into subscriber function 96
96
as an argument. 97
97
Now in practice, that means that 98
98
as soon as the program loads, the init function is called 99
99
which in turn immediately calls 100
100
the addHandlerRender function from the view. 101
101
And that is possible, remember, because the controller 102
102
does in fact import both the view and the model, right? 103
103
Now, anyway, as we call addHendlerRender, 104
104
we pass in our controlRecipes function as an argument. 105
105
So essentially, we subscribe controlRecipes 106
106
to addHandlerRender. 107
107
And so at this point, the two functions 108
108
are basically finally connected. 109
109
And so now addHandlerRender listens for events 110
110
using the addEventListener method as always. 111
111
And then as soon as the event actually happens, 112
112
the controlRecipes function will be called 113
113
as the callback function of addEventListener. 114
114
Or, in other words, 115
115
as soon as the publisher publishes an event 116
116
the subscriber will get called. 117
117
All right. 118
118
And this is how we implement event listeners 119
119
and event handlers in the MVC architecture. 120
120
So this will allow us to keep the handler in the controller 121
121
and to listener in the view. 122
122
And by that, keeping everything nicely separated. 123
123
So in summary, the handler subscribes to the publisher, 124
124
which is the listener in this case, 125
125
and then as the publisher publishes an event, 126
126
the subscriber is executed. 127
127
And if you want to think even deeper about this 128
128
and are really interested in this, 129
129
then notice how there is actually a profound difference 130
130
between a certain arbitrary like function A 131
131
simply calling function B directly 132
132
and function A receiving function B as an input 133
133
in order to then call that input function. 134
134
So this is all about control. 135
135
In the first scenario, function A is in control. 136
136
However, in the second scenario function A has no control. 137
137
So it simply has to execute whatever function it receives. 138
138
So if you want, reflect a little bit on that 139
139
and see that this is exactly 140
140
what the Publisher-Subscriber pattern is actually all about. 141
141
But anyway, leaving that theory aside now, 142
142
let's go back to our code and implement all of this. 143
143
And so with everything we just learned 144
144
about the Publisher-Subscriber pattern, 145
145
actually, now implementing it 146
146
should be the easiest part, right? 147
147
So let's simply grab this code. 148
148
So cutting it actually 149
149
and then here we will create a new method 150
150
and let's just put it somewhere, let's say here. 151
151
And so this will be our addHandlerRender method 152
152
that we just talked about. 153
153
So addHandlerRender because this is going to be 154
154
for rendering the recipe right at the beginning, right? 155
155
And then this method, which remember, is the publisher 156
156
basically needs to get access to the subscriber. 157
157
And so that in this case is the handler function. 158
158
All right? 159
159
And so then we can simply paste that in here. 160
160
And then here, of course we don't know about controlRecipes, 161
161
but we know about the handler. 162
162
And so that's actually it for this function. 163
163
So of course it is not a private method 164
164
because it needs to be part of the public API of this object 165
165
so that we can then call it in the controller, right. 166
166
And so let's actually do that now. 167
167
So we can get rid of this now. 168
168
And we will want to do this right in the beginning. 169
169
So let's create an init function here, 170
170
actually like this, 171
171
and then we simply call it right at the beginning. 172
172
So only once. 173
173
And actually we could simply put all the code 174
174
also here in the global scope, 175
175
but I think it's a bit cleaner 176
176
to have a separate function for this. 177
177
That's recipeView.addHandlerRender. 178
178
And so now we simply pass in controlRecipes, 179
179
and that's actually it. 180
180
With this, we just implemented 181
181
the Publisher-Subscriber pattern. 182
182
For some reason, we're still getting these errors here. 183
183
Let's get rid of this alert here actually, 184
184
and simply do a console.log here. 185
185
Okay. 186
186
But now let's go and see if this actually works. 187
187
We're still having our slow network. 188
188
Oh, and here we have some problem apparently 189
189
with the timeout. 190
190
So let's go quickly fix that here in the helpers. 191
191
So we saw that here it said undefined, 192
192
like after undefined second. 193
193
So maybe this variable here doesn't exist. 194
194
So maybe it's misspelled. 195
195
So let's see in the config. 196
196
Well, it looks right. 197
197
Yeah, it is the same. 198
198
Well, let's see again. 199
199
And so this apparently happens immediately 200
200
for some reason here. 201
201
So what if we put it back to some normal number? 202
202
Well, then it works, which is very weird 203
203
because this is in fact also 10. 204
204
So let's see what we get here as we lock timeout seconds. 205
205
Oh, I'm actually right now seeing the problem. 206
206
So this is not helpers, it is config. 207
207
So we are importing ourselves here. 208
208
So that was the problem. 209
209
Let's put everything back. 210
210
And you see that now it is working. 211
211
Even with the hashchange event. 212
212
And so that means that we did now successfully implement 213
213
the Publisher-Subscriber pattern. 214
214
Okay? 215
215
And so let's quickly recap what exactly is happening here. 216
216
So we can also take a look at our final diagram here. 217
217
And here, I actually have the event here in the controller 218
218
because that is actually where it is handled. 219
219
And so I think that in this diagram, 220
220
this makes it a little bit easier 221
221
to actually understand the flow of the program. 222
222
So anyway, as we start to program 223
223
then the init function runs 224
224
and it will then immediately run addHandlerRender, right? 225
225
So it is this function here. 226
226
And it's this function that is actually 227
227
listening for events right here in the view 228
228
where it actually makes sense. 229
229
Now, as we call this method here, so in the controller, 230
230
we pass in the controller function or the handler function 231
231
that we want to get executed as soon as the event happens, 232
232
right? 233
233
And here we then receive that function 234
234
as being called handler. 235
235
And so that's what we then call 236
236
as soon as the event happens, right? 237
237
And so again in our diagram, 238
238
that's exactly what we have here. 239
239
So that's why I have this dotted line here 240
240
which stands for data flow. 241
241
So we are passing in the controlRecipe function 242
242
as the handler here. 243
243
And that is the whole reason 244
244
why the method here is called addHandlerRender. 245
245
So because we are using it to, in fact, 246
246
add a handler function and in this case, 247
247
it is for rendering the recipe in the first place. 248
248
And then later on, 249
249
we will actually have other addHandler methods. 250
250
Okay? 251
251
And so it's crucial that you understand this logic here 252
252
before you can move on any further in this project. 253
253
But I hope that with all this explanation, 254
254
this became all really clear 255
255
and also obvious why we had to do it like this. 256
256
I mean, of course we don't really have to do it, 257
257
so we are, of course, in charge of our own code. 258
258
But in order to correctly implement the MVC architecture, 259
259
this is the best way of doing it. 260
260
And so again, then we can keep everything nicely separated 261
261
into a model controller and view 262
262
without any overlapping responsibilities. 263
263
All right. 264
264
So we have all of this structure here now nicely set up, 265
265
everything is nicely separated. 266
266
And so from now on, all we have to do 267
267
is to basically use this structure to implement 268
268
all of the missing features off our application. 269
269
And so again, really make sure that you understand 270
270
everything that we did so far, 271
271
especially regarding the implementation of our architecture. 272
272
And then once you are really done with understanding that, 273
273
let's go straight to the next video.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.