update tutorial

This commit is contained in:
dntzhang 2018-12-10 11:21:23 +08:00
parent 9acf8b886a
commit 6d54941a2d
3 changed files with 196 additions and 6 deletions

View File

@ -155,6 +155,114 @@ const res = mapping({ a: { b: 2, e: [{ f: 3 }, { f: 5 }, { f: 10 }] }, list: lis
})
```
### 小程序 MVVM Todo 实战
定义 TodoItem Model:
```js
let id = 0
export default class TodoItem {
constructor(text, completed) {
this.id = id++
this.text = text
this.completed = completed || false
}
}
```
定义 Todo Model:
```js
import TodoItem from './todo-item'
import { getAll, add } from './todo-server'
export default class Todo {
constructor() {
this.items = []
this.author = {
firstName: 'dnt',
lastName: 'zhang'
}
}
add(content) {
const item = new TodoItem(content)
this.items.push(item)
add(item)
}
complete(id) {
this.items.every(item => {
if (id === item.id) {
item.completed = true
return false
}
return true
})
}
uncomplete(id) {
this.items.every(item => {
if (id === item.id) {
item.completed = false
return false
}
return true
})
}
remove(id) {
this.items.every((item, index) => {
if (id === item.id) {
this.items.splice(index, 1)
return false
}
})
}
}
```
定义 ViewModel:
```js
import mapping from '../utils/mapping'
import todo from '../model/todo/index'
class TodoViewModel {
constructor() {
this.data = {
items: []
}
}
update() {
//一行代码,自动映射!!
mapping(todo, this.data)
}
toogleComplete(id) {
todo.toogleComplete(id)
this.update()
}
add(text) {
todo.add(text)
this.update()
}
remove(id) {
todo.remove(id)
this.update()
}
}
const vm = new TodoViewModel()
export default vm
```
说完 mappingjs来看下 mp-mvvm。你会发现mp-mvvm 和 omi-mvvm 的 web 模板有很多代码是一模一样的!
* Model 一模一样
@ -165,6 +273,94 @@ const res = mapping({ a: { b: 2, e: [{ f: 3 }, { f: 5 }, { f: 10 }] }, list: lis
> 领域模型复用不变View 可以移植成任意技术进行渲染
下面来看下小程序的 View
todo-list:
```html
<view>
<label class="checkbox {{item.completed&&'completed'}}" wx:for="{{items}}">
<view bindtap="checkboxChange" data-id="{{item.id}}">
<checkbox checked="{{item.completed}}" />
{{item.text}}
</view>
<image bindtap="remove" data-id="{{item.id}}" src="./remove.png" />
</label>
</view>
```
```js
import vm from '../../view-model/todo'
Component({
properties: {
items: {
type: Array,
value: []
}
},
ready: function() {},
methods: {
checkboxChange: function(e) {
vm.toogleComplete(e.currentTarget.dataset.id)
},
remove:function(e){
vm.remove(e.currentTarget.dataset.id)
}
}
})
```
这里把 todo-list 抽象成了一个自定义组件,因为需要有用户输入,所以把 vm 依赖进来,通过 vm 向 model 发指令并且更新视图。在看 todo page:
```html
<view class="container">
<view class="title">Hello MVVM</view>
<view>
<todo-list items="{{items}}" />
<view class="form">
<input class="input" bindinput="inputHandler" type="text" placeholder="Input your task" value="{{text}}" />
<button class="button" bindtap="tapHandler">Add{{items.length+1}}</button>
</view>
</view>
<other-view />
</view>
```
```js
import vm from '../../view-model/todo'
import create from '../../utils/create'
create.Page(vm, {
onLoad: function() {
vm.getAll()
},
inputHandler: function(e) {
this.text = e.detail.value
},
tapHandler: function() {
vm.add(this.text)
this.setData({
text: ''
})
}
})
```
需要注意的是,这是使用的是 `create.Page`,并传入了 `vm`,而非以前的 Page。这里需要介绍下两个新的 API
* create.Page(vm, options)
* create.Component(vm, options)
那么什么使用使用 create.Page 或者 create.Component什么时候不需要使用 create直接使用 Page 和 Component
* 如果只需要使用 vm 来发送指令,就不需要 create
* 如果你的 vm.data 需要作为视图的 data请使用 create
## License
MIT [@dntzhang](https://github.com/dntzhang)

View File

@ -2,9 +2,6 @@ import vm from '../../view-model/todo'
import create from '../../utils/create'
create.Page(vm, {
data: {
text: ''
},
onLoad: function() {
vm.getAll()
},

View File

@ -15,7 +15,6 @@ create.Page = function (vm, options) {
const kv = getArrayPatch(patch.path)
patchs[kv.k] = kv.v
timeout = setTimeout(() => {
console.log(patchs)
this.setData(patchs)
patchs = {}
})
@ -42,13 +41,11 @@ create.Component = function (vm, options) {
options.ready = function (e) {
vm.data = new JSONProxy(vm.data).observe(false, patch => {
console.log(11)
clearTimeout(timeout)
if (patch.op === 'remove') {//fix arr splice
const kv = getArrayPatch(patch.path)
patchs[kv.k] = kv.v
timeout = setTimeout(() => {
console.log(patchs)
this.setData(patchs)
patchs = {}
})