Skip to content

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:

  1. Make your own ViewModel implementation and interface with some customizations:
ts
// view-model.ts
// interface for your view model
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> {
  trackName: string;
  getTrackTime(): Date;
}
ts
// view-model.impl.ts
// implementation for your interface
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>
{
  trackName = new Date().toISOString()

  getTrackTime() {
    return new Date();
  }
}
  1. Make your own ViewModelStore implementation
ts
// view-model.store.impl.ts
import {
  ViewModelParams,
  ViewModelStoreBase,
  ViewModel,
  ViewModelCreateConfig,
} from 'mobx-view-model';
import { ViewModelImpl } from "./view-model.impl.ts"

export class ViewModelStoreImpl extends ViewModelStoreBase {
  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)
    if (ViewModelImpl.isPrototypeOf(VM)) {
      const instance = super.createViewModel(config) as unknown as ViewModelImpl;
      console.log(intance.getTrackTime());
      return instance;
    }

    // otherwise it will be default behaviour
    // of this method
    return super.createViewModel(config);
  }
}
  1. Create View with ViewModel
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;
    console.log(this.trackName)
    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);

Also you may be helpful to read this recipe about integration with RootStore

Released under the MIT License.