Skip to content

Commit 34fa83c

Browse files
author
Yu JiaZe(快站)
committed
done
1 parent a31b764 commit 34fa83c

9 files changed

+139
-32
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"babel-preset-es2016": "^6.16.0",
2929
"babel-preset-es2017": "^6.22.0",
3030
"babel-preset-react": "^6.0.0",
31+
"mobx-react-devtools": "^4.2.11",
3132
"react-hot-loader": "^3.0.0-beta.6",
3233
"ts-loader": "^2.0.0",
3334
"typescript": "^2.1.4",

src/app.tsx

+14-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import { TodoListView } from './component/TodoListView'
2-
import * as ReactDOM from 'react-dom'
3-
import { TodoList } from './store/TodoList'
4-
import { TodoItem } from './model/TodoItem'
5-
const store = new TodoList()
2+
import { TodoHeaderView } from './component/TodoHeaderView'
3+
import { TodoFooterView } from './component/TodoFooterView'
4+
import { observer, inject } from 'mobx-react'
5+
import DevTools from 'mobx-react-devtools'
66

7-
store.todos.push(
8-
new TodoItem("Get Coffee"),
9-
new TodoItem("Write simpler code")
7+
const App = observer(({stores}: { stores: any }) => {
8+
console.log(stores);
9+
return <div>
10+
<TodoHeaderView todos={stores} />
11+
<TodoListView todoList={stores} />
12+
<TodoFooterView stores={stores} />
13+
<DevTools />
14+
</div>
15+
}
1016
)
11-
store.todos[0].finished = true
12-
ReactDOM.render(<TodoListView todoList={store} />, document.getElementById('root'))
17+
export default App

src/component/TodoFooterView.tsx

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { observer } from 'mobx-react'
2+
import { action } from 'mobx'
3+
import { FILTER } from '../store/TodoList'
4+
5+
6+
export const TodoFooterView = observer(({stores}: { stores: any }) => {
7+
const _onClick = action(i => (stores.filter = FILTER[i as number]))
8+
function renderFilterLink() {
9+
let children = []
10+
for (let i in FILTER) {
11+
isNaN(parseInt(i)) && children.push(
12+
<a onClick={() => { _onClick(i) }} key={i}>
13+
{i}
14+
</a>
15+
)
16+
}
17+
return <div>{children}</div>
18+
}
19+
return (
20+
<div>
21+
{renderFilterLink()}
22+
<span>{stores.unfinishedTodoCount + ' items left'}</span>
23+
</div>
24+
)
25+
})

src/component/TodoHeaderView.tsx

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import * as React from 'react'
2+
import { ITodoList } from '../store/TodoList'
3+
import { observer } from 'mobx-react'
4+
5+
6+
export const TodoHeaderView = observer(({todos}: { todos: any }) => {
7+
function _onKeyDown(e) {
8+
if (e.keyCode == 13) {
9+
todos.add(e.target.value)
10+
e.target.value = ''
11+
}
12+
}
13+
14+
function _onClick(e) {
15+
todos.switchAll(_checked)
16+
_checked = !_checked
17+
}
18+
return (
19+
<div>
20+
<span onClick={_onClick}>swtich</span>
21+
<input type='text' onKeyDown={_onKeyDown} />
22+
</div>
23+
)
24+
})
25+
let _checked = true

src/component/TodoListView.tsx

+21-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { TodoItem, ITodoItem } from '../model/TodoItem'
22
import * as React from 'react'
3-
import { observer } from 'mobx-react'
4-
import { ITodoList } from '../store/TodoList'
3+
import { observer, inject } from 'mobx-react'
4+
import { ITodoList, FILTER } from '../store/TodoList'
55

66

77

@@ -18,24 +18,34 @@ const TodoItemView = observer(({todo}: { todo: ITodoItem }) => {
1818

1919
})
2020

21-
2221
@observer
23-
export class TodoListView extends React.Component<{ todoList: ITodoList<ITodoItem> }, {}>{
24-
public constructor(props: ITodoList<ITodoItem>) {
22+
export class TodoListView extends React.Component<{ todoList: any }, {}>{
23+
public constructor(props) {
2524
super(props)
2625
}
2726
public render() {
2827
return (
2928
<div>
3029
<ul>
31-
{
32-
this.props.todoList.todos.map(todo => (
33-
<TodoItemView todo={todo} key={todo.id} />
34-
))
35-
}
30+
{this.generateTodos()}
3631
</ul>
37-
Tasks Left : {this.props.todoList.unfinishedTodoCount}
3832
</div>
3933
)
4034
}
35+
private generateTodos() {
36+
switch (this.props.todoList.filter) {
37+
case FILTER.ALL:
38+
return this.props.todoList.todos.map(todo =>
39+
<TodoItemView todo={todo} key={todo.id} />
40+
)
41+
case FILTER.ACTIVE:
42+
return this.props.todoList.todos.filter(todo => todo.finished == false).map(todo =>
43+
<TodoItemView todo={todo} key={todo.id} />
44+
)
45+
case FILTER.COMPLETED:
46+
return this.props.todoList.todos.filter(todo => todo.finished == true).map(todo =>
47+
<TodoItemView todo={todo} key={todo.id} />
48+
)
49+
}
50+
}
4151
}

src/index.tsx

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import App from './App'
2+
import * as ReactDOM from 'react-dom'
3+
import { TodoList } from './store/TodoList'
4+
import { TodoItem } from './model/TodoItem'
5+
import { Provider } from 'mobx-react'
6+
const stores = new TodoList()
7+
8+
stores.todos.push(
9+
new TodoItem("Get Coffee"),
10+
new TodoItem("Write simpler code")
11+
)
12+
stores.todos[0].finished = true
13+
ReactDOM.render(
14+
<div>
15+
<Provider stores={stores}>
16+
<App stores={stores}/>
17+
</Provider>
18+
</div>,
19+
document.getElementById('root')
20+
)

src/model/TodoItem.tsx

+11-5
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,22 @@ export interface ITodoItem {
99
}
1010

1111
export class TodoItem {
12-
public id: number = Math.random()
13-
@observable public finished: boolean = false
14-
constructor( @observable public title: string = '') {
15-
12+
public readonly id: number = TodoItem.generateId()
13+
@observable
14+
public finished: boolean = false
15+
@observable
16+
public title: string = ''
17+
constructor(title) {
18+
this.title = title
1619
}
1720
public switch() {
1821
this.finished = !this.finished
1922
}
2023
public edit(newTitle: string) {
2124
this.title = newTitle
2225
}
23-
26+
static _id = 0
27+
static generateId(): number {
28+
return TodoItem._id++
29+
}
2430
}

src/store/TodoList.tsx

+21-6
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,40 @@
1-
import { observable, computed } from 'mobx'
1+
import { observable, computed, action } from 'mobx'
22
import { ITodoItem, TodoItem } from '../model/TodoItem'
33

4+
export enum FILTER {
5+
ALL = -1,
6+
ACTIVE = 0,
7+
COMPLETED = 1
8+
}
49

5-
export interface ITodoList<T> {
6-
todos: Array<T>
10+
export interface ITodoList {
11+
todos: Array<ITodoItem>
712
unfinishedTodoCount: number
13+
switchAll(checked: boolean): void
14+
delete(todo: ITodoItem): void
15+
add(title: string): void
816
}
917

1018

11-
export class TodoList<T extends ITodoItem> implements ITodoList<ITodoItem> {
12-
@observable todos: Array<T> = []
13-
@computed get unfinishedTodoCount(): number {
19+
export class TodoList implements ITodoList {
20+
@observable
21+
todos: Array<ITodoItem> = []
22+
@observable
23+
filter: number = FILTER.ALL
24+
@computed
25+
get unfinishedTodoCount(): number {
1426
return this.todos.filter(todo => !todo.finished).length
1527
}
28+
@action
1629
switchAll(checked: boolean) {
1730
this.todos.map(todo => todo.finished = checked)
1831
}
32+
@action
1933
delete(todo) {
2034
let idx = this.todos.indexOf(todo)
2135
this.todos.splice(idx, 1)
2236
}
37+
@action
2338
add(title: string) {
2439
this.todos.push(new TodoItem(title))
2540
}

webpack.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module.exports = {
55
"webpack-dev-server/client?http://127.0.0.1:8080",
66
// "webpack/hot/only-dev-server",
77
// 这里是你的入口文件
8-
"./src/app.tsx",
8+
"./src/index.tsx",
99
],
1010
output: {
1111
path: './public/',

0 commit comments

Comments
 (0)