使用 `Roof.Node` 非常简单。先使用 `Roof.Node` 创建用户自己的数据类型(以下都称为 **type**),再进行实例化。`Roof.Node` 不可以直接实例化。
javascript
var Roof = require('roof')
var User = Roof.Node.createClass()
var user = new User({name:roof, age:0, like:{sport:'basketball'})
API
get
简单读取数据
javascript
user.get('name')
深度读取
javascript
user.get('like.sport')
set
简单写数据
javascript
user.set("age", 1)
user.get("age") // 1
深度写入
javascript
user.set("tools",{
"node": "This node is not that node",
"bus" : "This bus is not that bus"
})
user.get("tools.node") //得到 This node is not that node
user.set("tools.bus", "Bus is event bus")
user.get("tools.bus") //得到 Bus is event bus
`set` 方法还支持更友好地批量修改:
javascript
user.set({name:"ava",age:1})
user.set({
"like.movie" : "Whisper",
"like.song" : "Tresspassing"
})
user.get("like") //得到{movie:"Whisper",song:"Tresspassing"}
要注意的是,如果 set 的数据是对象,那么保存的是它的引用。建议在set 完之后就不要在操作原来的对象,以免引起数据不一致。
javascript
var norah = {name:"norah"}
user.set("child",norah)
console.log( user.getRef("child") === norah ) //true
destroy
使用 `destroy` 方法即可销毁对象, 所有会修改到数据的 api 都被冻结了,调用时会抛出警告。
is
判断实例当前的状态,详见 **高级 API** 一节。
on
监听实例上的事件,详见 **监听数据事件** 一节。
fire
在实例上触发事件,监听实例上的事件,详见 **监听数据事件** 一节。
自定义 API
普通 API
用户在创建自己的 type 时,可以定义当前 type 特有的 API。
javascript
var User = Node.createClass({
setFullName : function( fullName ){
var tmp = fullName.split(' ')
this.set("name", tmp[0])
this.set("family", tmp[1])
},
getFullName : function(){
return this.get("name") +" "+this.get("family")
}
})
var user = new User({name:"Ian",family:"William"})
console.log(user.getFullName()) //"Ian William"
user.setFullName("Jhon Smith")
user.get('name') //"Jhon"
user.get('family') //"Smith"
高级 API (以下统称为 action)
定义 API 时,可以同时给它的状态取名字,配合 `is` 方法来判断。首先我们来定义一个 API doSometing,给它 “没有执行过” 的状态取名为 “doSomething.no”。给 “执行过” 的状态取名为 "doSomething.yes"。定义过状态的的 API 我们统称为 **action**, 和普通 API 区别开。
javasriptvar User = Roof.Node.createClass({ doSomething : [function(){ //do something },'doSomething.no','doSomething.yes'] })
判断它的状态
javasriptvar user = new User user.is('doSometing.no') //true user.is('doSometing.yes') //false user.doSomething() user.is('doSometing.no') //false user.is('doSometing.yes') //true
如果 action 的操作是异步的,那么可以定义三个状态:
javasriptvar User = Roof.Node.createClass({ doSomething : [function(){ //do something async return new Promise(function(resolve, reject){ setTimeout(function(){ resolve() },1000) }) },'doSomething.initial','doSomething.processing','doSomething.end'] }) var user = new User user.is('doSomething.initial') //true user.is('doSomething.processing') //true user.is('doSomething.end') //false var promise = user.doSomething() user.is('doSomething.prcessing') //true user.is('doSomething.end') //false promise.then(function(){ user.is('doSomething.end') //true })
`is` 可以同时判断多个状态:
javascript
user.is('a', 'b') //表示必须有 a 状态,也必须有 b 状态
user.is(['a','b']) //表示有 a 状态,或者有 b 状态
user.is(a,['b','c']) //表示有 a 状态,并且有 b 或者 c 状态
//is 支持无限多个参数
监听数据事件
当执行 action 时,Node 会将状态的变化作为事件抛出。注意,一定要在执行动作前调用 `on` 来监听。
javascript
var User = Roof.Node.createClass({
doSomething : [function(){
//do something
},'doSomething.no','doSomething.yes']
})
var user = new User
user.on('doSomething.yes', function(currentState, lastState){
currentState === 'doSomething.yes' //true
lastState === 'doSomething.no' //true
})
user.doSomething()
我们也可以使用 `fire` 方法手动触发事件,可以传递任意多个参数。注意,尽量不要手动触发 action 会触发的事件。
javascript
user.on('manualEvent', function( someArg ){
console.log('manualEvent fired', someArg )
})
user.fire('manualEvent', 'icecream')
除了监听具体的状态变化,我们还可以直接监听 `change` 事件,这个事件在任何状态变化时都会触发:
javascript
var User = Roof.Node.createClass({
doSomething : [function(){
//do something
},'doSomething.no','doSomething.yes']
})
var user = new User
user.on('change', function(currentState, lastState){
console.log(currentState) //doSomething.yes
console.log(lastState) //doSomething.no
})
user.doSomething()