├── README.md
├── app
├── lib
│ ├── API.js
│ ├── app.js
│ └── router.js
└── main.js
└── index.html
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
🍦 🍦 Vanilla JS 🍦 🍦
5 |
with CJ R.
6 |
7 |
8 | ---
9 |
10 | # M.V.C.
11 |
12 | ---
13 |
14 | ## We will need:
15 | * App
16 | * Component
17 | * model
18 | * view
19 | * controller
20 | * Router
21 | * API
22 |
23 | ---
24 |
25 |
26 |
27 | ---
28 |
29 | # CODE
30 |
31 | ---
32 |
33 |
34 |
35 |
36 |
As a lonely dog, I want to see a list of all of the dogs that are available so that I can see my dating options.
37 |
38 |
39 | ---
40 |
41 |
42 |
43 | ---
44 |
45 |
46 |
47 | ---
48 |
49 |
50 |
51 |
52 |
As a lonely dog, I want to be able to link to a specific dog so that I can share my favorite dogs with my friends.
53 |
54 |
55 | ---
56 |
57 |
58 |
59 | ---
60 |
61 |
62 |
63 | ---
64 |
65 |
66 |
67 |
72 |
73 | ---
74 |
75 |
76 |
77 | ---
78 |
79 | ## We made:
80 | * App
81 | * Component
82 | * model
83 | * view
84 | * controller
85 | * Router
86 | * API
87 |
88 | ----
89 |
90 | ## App
91 | * addComponent
92 | * showComponent
93 | * updateView
94 |
95 | ----
96 |
97 | ## Component
98 | * name
99 | * model
100 | * view
101 | * controller
102 |
103 | ----
104 |
105 | ## Router
106 | * addRoute
107 | * onHashChange
108 |
109 | ----
110 |
111 | ## API
112 | * getDogs
113 | * getDog
114 |
115 | ---
116 |
117 | # Conclusion
118 |
119 | ---
120 |
121 | # Should you do this in production?
122 |
123 | ----
124 |
125 |
126 |
127 | ----
128 |
129 | # Frameworks Exist For A Reason
130 |
131 | ---
132 |
133 | # Should you do this for fun?
134 |
135 | ----
136 |
137 |
138 |
139 | ----
140 |
141 | ### Answer the question:
142 | ### If you were to implement a library/framework/API feature from scratch, how would you do it?
143 |
144 | ---
145 |
146 | ## Links/Plugs
147 |
148 | * This code is here: [https://git.io/vanilla-js](https://git.io/vanilla-js)
149 | * [c.js - A simple MVC framework that no-one should use](https://github.com/w3cj/c.js)
150 | * [August 10th - Develop Denver: An OverVue of Vue.js](https://developdenver.org/talks/72)
151 | * Organizer of the [Vue.js Meetup](https://www.meetup.com/Denver-Vue-js-Meetup/)
152 | * Looking for full talk/lightning talk speakers for August 28th and September 25th
153 |
154 | ---
155 |
156 |
157 |
158 | ---
159 |
--------------------------------------------------------------------------------
/app/lib/API.js:
--------------------------------------------------------------------------------
1 | class API {
2 | constructor() {
3 | this.API_URL = 'https://barkwire-api.herokuapp.com/dogs';
4 | }
5 | getDogs() {
6 | return fetch(this.API_URL)
7 | .then(res => res.json());
8 | }
9 | getDog(id) {
10 | return fetch(`${this.API_URL}/${id}`)
11 | .then(res => res.json());
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/lib/app.js:
--------------------------------------------------------------------------------
1 | class App {
2 | constructor(selector) {
3 | this.appElement = document.querySelector(selector);
4 | this.componentsByName = {};
5 | }
6 | addComponent(component) {
7 | this.componentsByName[component.name] = component;
8 | component.model = this.proxify(component.model);
9 | }
10 | showComponent(name) {
11 | this.currentComponent = this.componentsByName[name];
12 |
13 | if(this.currentComponent) {
14 | this.currentComponent.controller(this.currentComponent.model);
15 | }
16 | this.updateView();
17 | }
18 | updateView() {
19 | if(this.currentComponent) {
20 | this.appElement.innerHTML = this.currentComponent.view(this.currentComponent.model);
21 | } else {
22 | this.appElement.innerHTML = 'Not Found
';
23 | }
24 | }
25 | proxify(model) {
26 | const self = this;
27 | return new Proxy(model, {
28 | set(target, property, value) {
29 | console.log('Changing', property, 'from', target[property], 'to', value);
30 | target[property] = value;
31 | self.updateView();
32 | return true;
33 | }
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/lib/router.js:
--------------------------------------------------------------------------------
1 | class Router {
2 | constructor(app) {
3 | this.app = app;
4 | this.routes = [];
5 | this.hashChange = this.hashChange.bind(this);
6 |
7 | window.addEventListener('hashchange', this.hashChange);
8 | window.addEventListener('DOMContentLoaded', this.hashChange);
9 | }
10 | addRoute(name, url) {
11 | this.routes.push({
12 | name,
13 | url
14 | });
15 | }
16 | hashChange() {
17 | const hash = window.location.hash;
18 | const route = this.routes.filter(route => hash.match(new RegExp(route.url)))[0];
19 |
20 | if(route) {
21 | this.params = new RegExp(route.url).exec(hash);
22 | this.app.showComponent(route.name);
23 | } else {
24 | this.app.showComponent();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/main.js:
--------------------------------------------------------------------------------
1 | const app = new App('#app');
2 | const api = new API();
3 |
4 | const dogTemplate = (dog) => `
5 |
17 | `;
18 |
19 | app.addComponent({
20 | name: 'dogs',
21 | model: {
22 | dogs: []
23 | },
24 | view(model) {
25 | const dogsHTML = model.dogs.reduce((html, dog) => html + `${dogTemplate(dog)}`, '')
26 | return `
27 |
30 | `;
31 | },
32 | controller(model) {
33 | api
34 | .getDogs()
35 | .then(result => {
36 | model.dogs = result.dogs;
37 | });
38 | }
39 | });
40 |
41 | app.addComponent({
42 | name: 'dog',
43 | model: {
44 | dog: {}
45 | },
46 | view(model) {
47 | return dogTemplate(model.dog);
48 | },
49 | controller(model) {
50 | api
51 | .getDog(router.params[1])
52 | .then(result => {
53 | model.dog = result.dog;
54 | });
55 | }
56 | });
57 |
58 | const router = new Router(app);
59 | router.addRoute('dogs', '^#/dogs$');
60 | router.addRoute('dog', '^#/dogs/([0-9]*)$');
61 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BarkWire
6 |
7 |
8 |
9 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------