Options: fields vs. model
fields vs. model
Either fields and model properties should be set. The former let's MobaseStore to take control over items' fields' assignment, the latter relies on custom implementation inside the model class.
fields :object
import {observable} from 'mobase'
options.fields = {
id: observable.ref, // in this case default == '' by default
arrayProp: {
modifier: observable.shallow,
default: []
},
mapProp: {
modifier: observable.shallowMap,
default: {}
},
computedProp: {
modifier: computed,
default() {
// this will be bound to item object
// thence this.id, this.arrayProp.slice(), etc will work fine
return `This item has ${this.arrayProp.size} arrayProp children`
}
}
}
Fields object is a collection where keys represent your store items' fields and values help MobaseStore to understand how to operate them. Each value is either an object of two props (modifier and default). Modifiers are MobX modifiers (see below for the list of supported modifiers):
myArraylikeProp: {
modifier: observable.shallow,
default: []
}
Or just a modifier. In this case default is set to an empty string by default
myTextProp: observable.ref
// equals to:
myTextProp: {
modifier: observable.ref,
default: ''
}
Supported modifiers:
For detailed modifiers description please reder to MobX documentation
observable used for plain values
options.fields = {
id: observable
}
myStore.get('-xcv1234-').id.get() // <-- access via get()
observable.ref used for plain values
options.fields = {
id: observable.ref,
text: observable
}
myStore.get('-xcv1234-').id.get() // <-- access via get()
observable.shallow for shallowly observed collections
(meaning it won't observe changes changed deeper than on the first level)
observable.map observable.shallowMap turns collections into MobX maps.
observable.deep is also supported
computed creates a computed value. default should be a function executed inside this computed. this will be bound to current item context:
import {observable, computed} from 'mobx'
options.fields = {
id: observable.ref,
name: observable.ref,
greeting: {
modifier: computed,
default() {
return `Hello ${this.name}. Your id is ${this.id}`
}
}
}
model :class
model should be set to a class, which will be instantiated each time a new item has to be created. The class should have a $mobaseFields setter property in order to work with incoming fields data:
Using custom model could be especially usefull when you want to create another mobase store inside a model to load some extra data.
import {observable, computed} from 'mobx'
import MobaseStore from 'mobase'
class Todo {
@observable _privateMember // MobaseStore won't write to Firebase properties starting with _ and $
@observable $commentsStore = null
@observable.ref id
@observable.ref text
@observable.ref isDone
@computed get comments() {
return this.$commentsStore ? this.$commentsStore.values() : []
}
onAfterChildAdded() {
this.$commentsStore = new MobaseStore({
path: '/todo_comments',
childId: this.id
)}
}
onBeforeChildRemoved() {
this.$commentsStore.unsubscribe() //re
}
}