Skip to content

Commit 036cc85

Browse files
committed
Split View into multiple classes
1 parent 8919e6e commit 036cc85

9 files changed

Lines changed: 205 additions & 31 deletions

File tree

‎src/week3/7-oop/README.md‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ In this application, we have provided a main View (called **PageView** below) an
6060
| -------- | ----------- |
6161
| index.html | The application's single HTML page. |
6262
| style.css | Contains the CSS styling. |
63-
| App.js | A JavaScript class that implements to the top-level component of the application. |
63+
| App.js | A JavaScript class that contains the main components of the application. |
6464
| Model.js | A JavaScript class that implements the Model functionality. |
65-
| PageView.js | A JavaScript class that implements the View functionality, rendering the Model data as HTML elements in the web page. |
66-
| ConsoleView.js | A JavaScript class that implements a (passive) View. It simply logs the Model data to the browser console. |
67-
| SpeechView.js | A JavaScript class that implements a (passive) View, rendering a summary of the Model data as spoken text. |
65+
| HeaderView.js | A JavaScript class that implements the View functionality, rendering the header with the select box. |
66+
| LaureatesView.js | A JavaScript class that implements the View functionality, rendering the laureates details. |
67+
| ErrorView.js | A JavaScript class that implements the View functionality, rendering an error, if any. |
68+
| SpeechView.js | A JavaScript class that implements the View functionality, rendering a summary of the Model data as spoken text. |
6869
| Observable.js | A JavaScript class that implements the Observable component of the [Observer pattern](https://en.wikipedia.org/wiki/Observer_pattern). |
70+
| Util.js | Contains utility functions. |
6971

7072
### Example Folders
7173

‎src/week3/7-oop/nobel-prize-classes/App.js‎

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
11
'use strict';
22

33
{
4-
const { Model, PageView, ConsoleView, SpeechView } = window;
4+
const { Model, HeaderView, LaureatesView, ErrorView, SpeechView } = window;
5+
const { createAndAppend } = window.Util;
56

67
class App {
78
constructor() {
9+
const containers = App.renderContainers();
10+
811
const model = new Model();
9-
this.pageView = new PageView(model);
10-
this.consoleView = new ConsoleView(model);
11-
this.speechSynthesizer = new SpeechView(model, 'en-GB');
12+
const fetchData = model.fetchData.bind(model);
13+
14+
model.subscribe(new HeaderView(containers.header, fetchData));
15+
model.subscribe(new LaureatesView(containers.main));
16+
model.subscribe(new ErrorView(containers.error));
17+
model.subscribe(new SpeechView('en-GB'));
18+
19+
fetchData();
20+
}
21+
22+
static renderContainers() {
23+
const root = document.getElementById('root');
24+
createAndAppend('h1', root, { text: 'Nobel Prize Laureates' });
25+
const header = createAndAppend('header', root);
26+
const error = createAndAppend('div', root);
27+
const main = createAndAppend('main', root, {
28+
id: 'main-container',
29+
});
30+
return { header, error, main };
1231
}
1332
}
1433

‎src/week3/7-oop/nobel-prize-classes/ConsoleView.js‎

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
{
4+
const { createAndAppend } = window.Util;
5+
6+
class ErrorView {
7+
constructor(container) {
8+
this.container = container;
9+
}
10+
11+
update(state) {
12+
this.render(state.error);
13+
}
14+
15+
render(error) {
16+
this.container.innerHTML = '';
17+
if (error) {
18+
createAndAppend('div', this.container, {
19+
text: error.message,
20+
class: 'alert alert-error',
21+
});
22+
}
23+
}
24+
}
25+
26+
window.ErrorView = ErrorView;
27+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
3+
{
4+
const { createAndAppend } = window.Util;
5+
6+
class HeaderView {
7+
constructor(header, fetchData) {
8+
this.header = header;
9+
this.fetchData = fetchData;
10+
this.select = null;
11+
}
12+
13+
update(state) {
14+
if (!this.select && !state.error) {
15+
this.render(state.countries);
16+
}
17+
}
18+
19+
render(countries) {
20+
this.select = createAndAppend('select', this.header);
21+
this.select.addEventListener('change', () =>
22+
this.fetchData(this.select.value),
23+
);
24+
25+
createAndAppend('option', this.select, {
26+
text: 'Select a country',
27+
disabled: 'disabled',
28+
selected: 'selected',
29+
});
30+
countries.forEach((country, index) =>
31+
createAndAppend('option', this.select, {
32+
text: country.name,
33+
value: index,
34+
}),
35+
);
36+
}
37+
}
38+
39+
window.HeaderView = HeaderView;
40+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
'use strict';
2+
3+
{
4+
const { createAndAppend } = window.Util;
5+
6+
class LaureatesView {
7+
constructor(container) {
8+
this.container = container;
9+
}
10+
11+
update(state) {
12+
if (!state.error && state.laureates != null) {
13+
this.render(state.laureates);
14+
}
15+
}
16+
17+
render(laureates) {
18+
this.container.innerHTML = '';
19+
if (laureates.length === 0) {
20+
createAndAppend('h4', this.container, {
21+
text: 'No laureates found',
22+
});
23+
return;
24+
}
25+
const ul = createAndAppend('ul', this.container, {
26+
id: 'list-container',
27+
});
28+
laureates.forEach(laureate => {
29+
const { surname, firstname } = laureate;
30+
const li = createAndAppend('li', ul, {
31+
class: 'list-item',
32+
});
33+
const table = createAndAppend('table', li);
34+
const tbody = createAndAppend('tbody', table);
35+
this.addRow(tbody, 'Name', `${firstname} ${surname || ''} `);
36+
this.addRow(
37+
tbody,
38+
'Born',
39+
`${laureate.born}, ${laureate.bornCity}, ${laureate.bornCountry}`,
40+
);
41+
if (laureate.died !== '0000-00-00') {
42+
this.addRow(
43+
tbody,
44+
'Died',
45+
`${laureate.died}, ${laureate.diedCity}, ${laureate.diedCountry}`,
46+
);
47+
}
48+
this.renderLaureatePrizes(tbody, laureate.prizes);
49+
});
50+
}
51+
52+
renderLaureatePrizes(tbody, prizes) {
53+
const tr = createAndAppend('tr', tbody);
54+
createAndAppend('th', tr, { text: 'Prizes:', class: 'label' });
55+
const td = createAndAppend('td', tr);
56+
const ul = createAndAppend('ul', td);
57+
prizes.forEach(prize => {
58+
const li = createAndAppend('li', ul);
59+
createAndAppend('span', li, {
60+
text: `${prize.year}, ${prize.category}`,
61+
});
62+
if (prize.motivation) {
63+
createAndAppend('span', li, {
64+
text: `: ${prize.motivation}`,
65+
class: 'motivation',
66+
});
67+
}
68+
});
69+
}
70+
71+
addRow(tbody, label, value) {
72+
const row = createAndAppend('tr', tbody);
73+
createAndAppend('th', row, {
74+
text: `${label}:`,
75+
class: 'label',
76+
});
77+
createAndAppend('td', row, { text: value });
78+
return row;
79+
}
80+
}
81+
82+
window.LaureatesView = LaureatesView;
83+
}

‎src/week3/7-oop/nobel-prize-classes/SpeechView.js‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
{
44
class SpeechView {
5-
constructor(model, lang) {
6-
model.subscribe(this);
7-
this.count = 0;
5+
constructor(lang) {
86
this.lang = lang;
97
this.utterance = null;
108
this.voices = null;
@@ -25,7 +23,7 @@
2523
this.speak(
2624
`There ${chunks[0]} ${laureates.length} laureate${
2725
chunks[1]
28-
} in ${former} ${selectedCountry.name}.`,
26+
} born in ${former} ${selectedCountry.name}.`,
2927
);
3028
}
3129
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
{
4+
class Util {
5+
static createAndAppend(name, parent, options = {}) {
6+
const elem = document.createElement(name);
7+
parent.appendChild(elem);
8+
Object.entries(options).forEach(([key, value]) => {
9+
if (key === 'text') {
10+
elem.textContent = value;
11+
} else {
12+
elem.setAttribute(key, value);
13+
}
14+
});
15+
return elem;
16+
}
17+
}
18+
19+
window.Util = Util;
20+
}

‎src/week3/7-oop/nobel-prize-classes/index.html‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414

1515
<body>
1616
<div id="root"></div>
17+
<script src="Util.js"></script>
1718
<script src="Observable.js"></script>
1819
<script src="Model.js"></script>
19-
<script src="PageView.js"></script>
20-
<script src="ConsoleView.js"></script>
20+
<script src="HeaderView.js"></script>
21+
<script src="LaureatesView.js"></script>
22+
<script src="ErrorView.js"></script>
2123
<script src="SpeechView.js"></script>
2224
<script src="App.js"></script>
2325
</body>

0 commit comments

Comments
 (0)