Detailed configuration
This way can be helpful when:
- if you need to override default factory method of creating view model instances in ViewModelStore.
- if you need to inject root store into ViewModelStore.
- if you need more control of the mounting\unmounting ViewModels.
Follow the steps:
- Make your own ViewModelStore implementation
ts
import {
ViewModelParams,
ViewModelStoreBase,
ViewModel,
ViewModelCreateConfig,
} from 'mobx-view-model';
export class ViewModelStoreImpl extends ViewModelStoreBase {
constructor(protected rootStore: RootStore) {
super();
}
createViewModel<VM extends ViewModel<any, ViewModel<any, any>>>(
config: ViewModelCreateConfig<VM>,
): VM {
const VM = config.VM;
// here is you sending rootStore as
// first argument into VM (your view model implementation)
return new VM(this.rootStore, config);
}
}
- Make your own
ViewModel
implementation with sharingRootStore
ts
// view-model.ts
import { ViewModel as ViewModelBase } from 'mobx-view-model';
export interface ViewModel<
Payload extends AnyObject = EmptyObject,
ParentViewModel extends ViewModel<any> = ViewModel<any, any>,
> extends ViewModelBase<Payload, ParentViewModel> {}
ts
import { ViewModelBase, ViewModelParams } from 'mobx-view-model';
import { ViewModel } from './view-model';
export class ViewModelImpl<
Payload extends AnyObject = EmptyObject,
ParentViewModel extends ViewModel<any> = ViewModel<any>,
>
extends ViewModelBase<Payload, ParentViewModel>
implements ViewModel<Payload, ParentViewModel>
{
constructor(
protected rootStore: RootStore,
params: ViewModelParams<Payload, ParentViewModel>,
) {
super(params);
}
get queryParams() {
return this.rootStore.router.queryParams.data;
}
protected getParentViewModel(
parentViewModelId: Maybe<string>,
): ParentViewModel | null {
return this.rootStore.viewModels.get<ParentViewModel>(parentViewModelId);
}
}
- Add
ViewModelStore
into yourRootStore
ts
import { ViewModelStore } from 'mobx-view-model';
import { ViewModelStoreImpl } from '@/shared/lib/mobx';
export class RootStoreImpl implements RootStore {
viewModels: ViewModelStore;
constructor() {
this.viewModels = new ViewModelStoreImpl(this);
}
}
- Create
View
withViewModel
tsx
import { ViewModelProps, withViewModel } from 'mobx-view-model';
import { ViewModelImpl } from '@/shared/lib/mobx';
export class MyPageVM extends ViewModelImpl {
@observable
accessor state = '';
async mount() {
// this.isMounted = false;
await this.rootStore.beerApi.takeBeer();
super.mount(); // this.isMounted = true
}
didMount() {
console.info('did mount');
}
unmount() {
super.unmount();
}
}
const MyPageView = observer(({ model }: ViewModelProps<MyPageVM>) => {
return <div>{model.state}</div>;
});
export const MyPage = withViewModel(MyPageVM)(MyPageView);