observable use proxy to return a proxy object, the proxy object can be monitored by observe.
1
| import { observable } from "dob"
|
Usage
1 2 3 4 5 6 7 8
| observable(obj)
@observable class Obj { someField = ".." }
|
Features
observable support native object、array、Map、WeakMap、Set、WeakSet, support undefined variables, dynamic conditional branches.
Object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const obj = observable({ user: { name: "jeck", age: 25, } }) observe(() => { console.log(`${obj.user.name}, ${obj.user.age}`) }) obj.user.name = "bob" obj.user = { name: "well", age: 16, } delete obj.user.name
|
Array
Only when the variables used are modified, the action will be triggered again.
1 2 3 4 5 6 7 8 9
| let arr = observable([1, 2, 3, 4, 5]) observe(() => { console.log(`${arr.map(i => i)}`) }) arr[0] = 10 arr.push(6) Action(()=>{ arr.shift() }) Action(()=>{ arr.splice(2, 1) }) delete arr[0]
|
Because of JS achieve shift splice by divided into multiple steps, so use Action can be aggregated into an action.
.length will trigger action when any change, which will change array’s length:
1 2 3 4 5 6
| let arr = observable([1, 2, 3, 4, 5]) observe(() => { console.log(`${arr.length}`) }) arr.push(6) arr.splice(2, 1)
|
Map
listen size:
1 2 3 4 5 6 7
| const map = observable(new Map()) observe(() => { console.log(`${map.size}`) }) map.set("banana", 5) map.set("apple", 3) map.clear()
|
listen single key:
1 2 3 4 5
| const map = observable(new Map()) observe(() => { console.log(`${map1.get("apple")}`) }) map1.set("apple", 6)
|
WeakMap
Same with Map.
Set
listen size:
1 2 3 4 5 6 7
| const set = observable(new Set()) observe(() => { console.log(`${set.size}`) }) set.add("banana") set.add("apple") set.clear()
|
WeakSet
Same with Set.
Expand thinking
All of the basic type as shown above can be used in object:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const obj = observable({ simpleNumber: 1, simpleString: "text~", simpleArray: [1, 2, 3, 4, 5], map: new Map([ ["a", 1], ["b", 2], ["c", 3] ]), deepObj: { user: { articles: [{ title: "nodejs" }] } }, show: false })
|
Dynamic binding
For uninitialized variables, can also be tracked.
1 2 3 4 5
| const obj = observable({}) observe(() => { log('#demo-dynamic-binding div', `${obj.a}`) }) obj.a = 3
|
Conditional branch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const objCon = observable({ useA: true, a: 1, b: 2 })
observe(() => { if (objCon.useA) { console.log(objCon.a) } })
objCon.a = 3 objCon.useA = false objCon.a = 4
|