Skip to content
Snippets Groups Projects
Commit 97bd1327 authored by Will Billingsley's avatar Will Billingsley
Browse files

Merge branch 'master' into vue-solution

parents 71a41bdf 1d8f19c5
Branches
No related tags found
No related merge requests found
......@@ -250,3 +250,141 @@ let v = new Vue({
}
})
```
### Making ConfigView alter the config
Next, let's go back to `gameConfig.ts` and make our ConfigView render something more interesting that actually alters the fields.
The full HTML of the component's template in the solution is quite long, but that's because I've used Bootstrap's components to make it look pretty — the Vue aspects are quite small in there. So rather than talk you through all of my solution HTML, let's just do a short and not-so-pretty version here.
We're going to need input elements for the width and height of the grid.
The `config` prop we've passed in is read-only. But it's a *read-only reference* to a *mutable object*. So we're going to bind some input controls to its fields.
First, in the component's template, we need inputs for the width and height:
```ts
template: `
<div>
Columns:
<input type="number" v-model:value="config.w" />
Rows:
<input type="number" v-model:value="config.w" />
</div>
`,
```
We've used `v-model` rather than `v-bind` to give us a two-way binding between the value of the input field and the value of `config.w` and `config.h`. Remember, we can't alter `config` (the reference) but we can alter its fields.
If you reload the page, you should now have some fields above the grid, and they should appear initialised to 40 and 20.
Next, let's wire up a Create button. Inside the component's template, put:
```ts
<button v-bind:disabled="config.created" v-on:click="create">Create</button>
```
This bind's the button's "disabled" attribute so that it will become disabled when `config.created` becomes true. And it sets the button so that when it is clicked it will call `create()` in the component's class. We'd better go and make the create function. Remember, it needs to be a method on the ConfigView class:
```ts
create() {
console.log("Create was pressed")
this.config.created = true
}
```
Reload and check that logs to the browser console when you hit the button (and the button should also become disabled).
### Altering render
We need to let our component actually configure our `Life` instance.
First, in `life.ts`, let's turn `life` into a variable, and also add a create function that accepts a `GameConfig` and a function for getting the value of life.
```ts
import { GameConfig } from "./gameConfig"
```
```ts
let life:Life = new Life(0,0)
function create(config:GameConfig) {
console.log(config.w)
life = new Life(config.w, config.h)
render()
}
function getLife() {
return life
}
```
Next, make sure those are exported
```ts
export {
getLife as getLife,
create as create,
render as render
}
```
### Making ConfigView set up the game
Let's go back to `gameConfig.ts` and import those definitions
```ts
import { create, render, getLife } from './render'
```
We can now alter the definition of our `create()` method on `ConfigView` to actually call `create` in `render.ts`:
```ts
create() {
create(this.config) // note this calls create in render.ts that we imported
render()
this.config.created = true
}
```
Reload, and see if it works.
### Setting up the timer
JavaScript timers give you a timer id that is a number. So in our `ConfigView` class let's add a field that can remember it. This is not a prop, just an ordinary field on the class. And the `?` means it might be null.
```ts
intervalId?: number
```
Let's now create a method on the class that can start and stop an actual timer using this field. Notice that we're using the `getLife` and `render` functions from `render.ts` that we imported.
```ts
toggleTimer() {
if (this.config.started) {
clearInterval(this.intervalId)
this.config.started = false
} else {
this.intervalId = setInterval(() => {
let l = getLife()
if (l) l.stepGame()
render()
}, this.config.period)
this.config.started = true
}
}
```
And now all we need do is add some HTML to the template that'll reference the remaining fields of our `GameConfig` and will call this method:
```ts
Period:
<input type="number" v-model:value="config.period" />
<button v-bind:disabled="!config.created" v-on:click="toggleTimer">
{{ config.started ? "Stop" : "Start" }}
</button>
```
Notice this button is bound so it's disabled until we've created the game. It's onClick is bound to the `toggleTimer` method, and the text changes from Start to Stop depending on whether the timer is already started.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment