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
}
}