Merge pull request #1544 from alexander-travov/rewrite
[rewrite: docs] Tutorial fixes
This commit is contained in:
commit
925a9ebc70
1 changed files with 45 additions and 45 deletions
|
|
@ -13,14 +13,14 @@ First let's create an entry point for the application. Create a file `index.html
|
|||
<title>My Application</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="app.js"></script>
|
||||
<script src="bin/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
The `<!doctype html>` line indicates this is an HTML 5 document. The first `charset` meta tag indicates the encoding of the document and the `viewport` meta tag dictates how mobile browsers should scale the page. The `title` tag contains the text to be displayed on the browser tab for this application, and the `script` tag indicates what is the path to the Javascript file that controls the application.
|
||||
|
||||
We could create the entire application in a single Javascript file, but doing so would make it difficult to navigate the codebase later on. Instead, let's split the code into *modules*, and assemble these modules into a *bundle* `app.js`.
|
||||
We could create the entire application in a single Javascript file, but doing so would make it difficult to navigate the codebase later on. Instead, let's split the code into *modules*, and assemble these modules into a *bundle* `bin/app.js`.
|
||||
|
||||
There are many ways to setup a bundler tool, but most are distributed via NPM. In fact, most modern Javascript libraries and tools are distributed that way, including Mithril. NPM stands for Node.js Package Manager. To download NPM, [install Node.js](https://nodejs.org/en/); NPM is installed automatically with it. Once you have Node.js and NPM installed, open the command line and run this command:
|
||||
|
||||
|
|
@ -61,7 +61,7 @@ module.exports = User
|
|||
Next we create a function that will trigger an XHR call. Let's call it `loadList`
|
||||
|
||||
```javascript
|
||||
// models/User.js
|
||||
// src/models/User.js
|
||||
var m = require("mithril")
|
||||
|
||||
var User = {
|
||||
|
|
@ -77,7 +77,7 @@ module.exports = User
|
|||
Then we can add an `m.request` call to make an XHR request. For this tutorial, we'll make XHR calls to the [REM](http://rem-rest-api.herokuapp.com/) API, a mock REST API designed for rapid prototyping. This API returns a list of users from the `GET http://rem-rest-api.herokuapp.com/api/users` endpoint. Let's use `m.request` to make an XHR request and populate our data with the response of that endpoint.
|
||||
|
||||
```javascript
|
||||
// models/User.js
|
||||
// src/models/User.js
|
||||
var m = require("mithril")
|
||||
|
||||
var User = {
|
||||
|
|
@ -99,7 +99,7 @@ module.exports = User
|
|||
|
||||
The `method` option is an [HTTP method](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods). To retrieve data from the server without causing side-effects on the server, we need to use the `GET` method. The `url` is the address for the API endpoint. The `withCredentials: true` line indicates that we're using cookies (which is a requirement for the REM API).
|
||||
|
||||
The `m.request` call returns a Promise that resolves to the data from the endpoint. By default, Mithril assumes a HTTP response body are in JSON format and automatically parses it into a Javascript object or array. The `.then` callback runs when the XHR request completes. In this case, the callback assigns the `reesult.data` array to `User.list`.
|
||||
The `m.request` call returns a Promise that resolves to the data from the endpoint. By default, Mithril assumes a HTTP response body are in JSON format and automatically parses it into a Javascript object or array. The `.then` callback runs when the XHR request completes. In this case, the callback assigns the `result.data` array to `User.list`.
|
||||
|
||||
Notice we also have a `return` statement in `loadList`. This is a general good practice when working with Promises, which allows us to register more callbacks to run after the completion of the XHR request.
|
||||
|
||||
|
|
@ -112,15 +112,17 @@ Now, let's create a view module so that we can display data from our User model
|
|||
Create a file called `src/views/UserList.js`. First, let's include Mithril and our model, since we'll need to use both:
|
||||
|
||||
```javascript
|
||||
// src/views/UserList.js
|
||||
var m = require("mithril")
|
||||
var User = require("../model/User")
|
||||
var User = require("../models/User")
|
||||
```
|
||||
|
||||
Next, let's create a Mithril component. A component is simply an object that has a `view` method:
|
||||
|
||||
```javascript
|
||||
// src/views/UserList.js
|
||||
var m = require("mithril")
|
||||
var User = require("../model/User")
|
||||
var User = require("../models/User")
|
||||
|
||||
module.exports = {
|
||||
view: function() {
|
||||
|
|
@ -135,7 +137,7 @@ Let's use Mithril hyperscript to create a list of items. Hyperscript is the most
|
|||
|
||||
```javascript
|
||||
var m = require("mithril")
|
||||
var User = require("../model/User")
|
||||
var User = require("../models/User")
|
||||
|
||||
module.exports = {
|
||||
view: function() {
|
||||
|
|
@ -149,16 +151,15 @@ The `".user-list"` string is a CSS selector, and as you would expect, `.user-lis
|
|||
Now, let's reference the list of users from the model we created earlier (`User.list`) to dynamically loop through data:
|
||||
|
||||
```javascript
|
||||
// src/views/UserList.js
|
||||
var m = require("mithril")
|
||||
var User = require("../model/User")
|
||||
var User = require("../models/User")
|
||||
|
||||
module.exports = {
|
||||
view: function() {
|
||||
return m(".user-list", [
|
||||
User.list.map(function(user) {
|
||||
return m(".user-list-item", user.firstName + " " + user.lastName)
|
||||
})
|
||||
])
|
||||
return m(".user-list", User.list.map(function(user) {
|
||||
return m(".user-list-item", user.firstName + " " + user.lastName)
|
||||
}))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -168,17 +169,16 @@ Since `User.list` is a Javascript array, and since hyperscript views are just Ja
|
|||
The problem, of course, is that we never called the `User.loadList` function. Therefore, `User.list` is still an empty array, and thus this view would render a blank page. Since we want `User.loadList` to be called when we render this component, we can take advantage of component [lifecycle methods](lifecycle-methods.md):
|
||||
|
||||
```javascript
|
||||
// src/views/UserList.js
|
||||
var m = require("mithril")
|
||||
var User = require("../model/User")
|
||||
var User = require("../models/User")
|
||||
|
||||
module.exports = {
|
||||
oninit: User.loadList,
|
||||
view: function() {
|
||||
return m(".user-list", [
|
||||
User.list.map(function(user) {
|
||||
return m(".user-list-item", user.firstName + " " + user.lastName)
|
||||
})
|
||||
])
|
||||
return m(".user-list", User.list.map(function(user) {
|
||||
return m(".user-list-item", user.firstName + " " + user.lastName)
|
||||
}))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -189,12 +189,13 @@ Also notice we **didn't** do `oninit: User.loadList()` (with parentheses at the
|
|||
|
||||
---
|
||||
|
||||
Let's render the view from the entry point file `index.js` we created earlier:
|
||||
Let's render the view from the entry point file `src/index.js` we created earlier:
|
||||
|
||||
```javascript
|
||||
// src/index.js
|
||||
var m = require("mithril")
|
||||
|
||||
var UserList = require("./view/UserList")
|
||||
var UserList = require("./views/UserList")
|
||||
|
||||
m.mount(document.body, UserList)
|
||||
```
|
||||
|
|
@ -221,7 +222,7 @@ To add styles, let's first create a file called `styles.css` and include it in t
|
|||
<link href="styles.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<script src="app.js"></script>
|
||||
<script src="bin/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
|
@ -249,9 +250,10 @@ Routing means binding a screen to a unique URL, to create the ability to go from
|
|||
We can add routing by changing the `m.mount` call to a `m.route` call:
|
||||
|
||||
```javascript
|
||||
// src/index.js
|
||||
var m = require("mithril")
|
||||
|
||||
var UserList = require("./view/UserList")
|
||||
var UserList = require("./views/UserList")
|
||||
|
||||
m.route(document.body, "/list", {
|
||||
"/list": UserList
|
||||
|
|
@ -278,14 +280,14 @@ module.exports = {
|
|||
}
|
||||
```
|
||||
|
||||
Then we can `require` this new module from `index.js`
|
||||
Then we can `require` this new module from `src/index.js`
|
||||
|
||||
```javascript
|
||||
// index.js
|
||||
// src/index.js
|
||||
var m = require("mithril")
|
||||
|
||||
var UserList = require("./view/UserList")
|
||||
var UserForm = require("./view/UserForm")
|
||||
var UserList = require("./views/UserList")
|
||||
var UserForm = require("./views/UserForm")
|
||||
|
||||
m.route(document.body, "/list", {
|
||||
"/list": UserList
|
||||
|
|
@ -295,11 +297,11 @@ m.route(document.body, "/list", {
|
|||
And finally, we can create a route that references it:
|
||||
|
||||
```javascript
|
||||
// index.js
|
||||
// src/index.js
|
||||
var m = require("mithril")
|
||||
|
||||
var UserList = require("./view/UserList")
|
||||
var UserForm = require("./view/UserForm")
|
||||
var UserList = require("./views/UserList")
|
||||
var UserForm = require("./views/UserForm")
|
||||
|
||||
m.route(document.body, "/list", {
|
||||
"/list": UserList,
|
||||
|
|
@ -344,7 +346,7 @@ body,.input,.button {font:normal 16px Verdana;margin:0;}
|
|||
.button:hover {background:#e8e8e8;}
|
||||
```
|
||||
|
||||
Right now, this component does nothing to respond to user events. Let's add some code to our `User` model in `src/model/User.js`. This is how the code is right now:
|
||||
Right now, this component does nothing to respond to user events. Let's add some code to our `User` model in `src/models/User.js`. This is how the code is right now:
|
||||
|
||||
```javascript
|
||||
// src/models/User.js
|
||||
|
|
@ -408,7 +410,7 @@ Notice we added a `User.current` property, and a `User.load(id)` method which po
|
|||
```javascript
|
||||
// src/views/UserForm.js
|
||||
var m = require("mithril")
|
||||
var User = require("./model/User")
|
||||
var User = require("../models/User")
|
||||
|
||||
module.exports = {
|
||||
oninit: function(vnode) {User.load(vnode.attrs.id)},
|
||||
|
|
@ -431,16 +433,14 @@ Now, let's modify the `UserList` view so that we can navigate from there to a `U
|
|||
```javascript
|
||||
// src/views/UserList.js
|
||||
var m = require("mithril")
|
||||
var User = require("../model/User")
|
||||
var User = require("../models/User")
|
||||
|
||||
module.exports = {
|
||||
oninit: User.loadList,
|
||||
view: function() {
|
||||
return m(".user-list", [
|
||||
User.list.map(function(user) {
|
||||
return m("a.user-list-item", {href: "/edit/" + user.id, oncreate: m.route.link}, user.firstName + " " + user.lastName)
|
||||
})
|
||||
])
|
||||
return m(".user-list", User.list.map(function(user) {
|
||||
return m("a.user-list-item", {href: "/edit/" + user.id, oncreate: m.route.link}, user.firstName + " " + user.lastName)
|
||||
}))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -456,7 +456,7 @@ The form itself still doesn't save when you press "Save". Let's make this form w
|
|||
```javascript
|
||||
// src/views/UserForm.js
|
||||
var m = require("mithril")
|
||||
var User = require("../model/User")
|
||||
var User = require("../models/User")
|
||||
|
||||
module.exports = {
|
||||
oninit: function(vnode) {User.load(vnode.attrs.id)},
|
||||
|
|
@ -573,15 +573,15 @@ body,.input,.button {font:normal 16px Verdana;margin:0;}
|
|||
.button:hover {background:#e8e8e8;}
|
||||
```
|
||||
|
||||
Let's change the router in `index.js` to add our layout into the mix:
|
||||
Let's change the router in `src/index.js` to add our layout into the mix:
|
||||
|
||||
```javascript
|
||||
// index.js
|
||||
// src/index.js
|
||||
var m = require("mithril")
|
||||
|
||||
var UserList = require("./view/UserList")
|
||||
var UserForm = require("./view/UserForm")
|
||||
var Layout = require("./view/Layout")
|
||||
var UserList = require("./views/UserList")
|
||||
var UserForm = require("./views/UserForm")
|
||||
var Layout = require("./views/Layout")
|
||||
|
||||
m.route(document.body, "/list", {
|
||||
"/list": {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue