Closed Amareis closed 4 years ago
Since nodes in mobx-keystone cannot become dead there's no direct equivalent. However you can use the hook that runs whenever a node is detached from a root store node (the function that you return from onAttachedToRootStore) (https://mobx-keystone.js.org/rootStores) or alternatively onChildAttachedTo (https://mobx-keystone.js.org/treeLikeStructure#onchildattachedtotarget---object-fn-child-object----void--void-options--deep-boolean-fireforcurrentchildren-boolean--rundetachdisposers-boolean--void) to kind of emulate this.
Yep, I already make such wrappers:
import {AnyModel, getRootStore, model, ModelClass} from 'mobx-keystone'
const $disposers = Symbol('disposers')
export type Disposer = () => void
export const coolModel: typeof model = name => clazz => {
if ('onAttachedToRootStore' in clazz.prototype)
throw new Error("Don't use onAttachedToRootStore!")
clazz.prototype.onAttachedToRootStore = function onAttachedToRootStore(root: any) {
this[$disposers] = [] as Disposer[]
this.onAttach?.(root)
return () => {
this[$disposers]?.forEach((d: Disposer) => d())
delete this[$disposers]
}
}
return model(name)(clazz)
}
export function addDisposer(node: AnyModel, disposer: Disposer) {
if (!($disposers in node))
throw new Error('Model is not attached to root store!')
// @ts-ignore
node[$disposers].push(disposer)
}
I think, set of such wrappers can be published as package for tiny mst-compatibility layer, #156 related
This snippet works, but does disposer from onAttachedToRootStore
is running after actual detaching? It's not good, child node sometimes need to use some root node methods to correct dispose itself.
Yes, it runs after being attached and after being detached. Since it runs as a disposer and the hook takes the root store it gets attached to as a parameter you can still call root store methods on those. e.g.
onAttachedToRootStore(rootStore) {
return () => {
// already detached, call old root store method
rootStore.whatever(this);
};
}
Have you found a use case that is not covered with this pattern?
Have you found a use case that is not covered with this pattern?
Nope, I adapt my code to store root reference too. So, basically, addDisposer can be easily implemented in user-land.
Hi! Currently I translated out project from mst to keystone, and we actively using
addDisposer
. Does it possible to implement it in keystone?