Skip to content

Commit 246fa9f

Browse files
committed
docs: add integration with RootStore recipe
1 parent d9f238a commit 246fa9f

File tree

4 files changed

+154
-39
lines changed

4 files changed

+154
-39
lines changed

docs/.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ export default defineConfig({
190190
text: 'Recipes',
191191
items: [
192192
{ text: 'Wrap in observer() all view components', link: '/recipes/observer-wrap-all-view-components' },
193+
{ text: 'Integration with RootStore', link: '/recipes/integration-with-root-store' },
193194
]
194195
},
195196
{

docs/introduction/usage/detailed-configuration.md

Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,23 @@ This way can be helpful when:
88

99
Follow the steps:
1010

11-
1. Make your own `ViewModel` implementation with accepting `RootStore` as `constructor` parameter
11+
1. Make your own `ViewModel` implementation and interface with some customizations:
1212

13-
```ts
13+
```ts{9,10}
1414
// view-model.ts
1515
// interface for your view model
1616
import { ViewModel as ViewModelBase } from 'mobx-view-model';
1717
1818
export interface ViewModel<
1919
Payload extends AnyObject = EmptyObject,
2020
ParentViewModel extends ViewModel<any> = ViewModel<any, any>,
21-
> extends ViewModelBase<Payload, ParentViewModel> {}
21+
> extends ViewModelBase<Payload, ParentViewModel> {
22+
trackName: string;
23+
getTrackTime(): Date;
24+
}
2225
```
2326

24-
```ts{15}
27+
```ts{5,12,14,16,17,18}
2528
// view-model.impl.ts
2629
// implementation for your interface
2730
import { ViewModelBase, ViewModelParams } from 'mobx-view-model';
@@ -35,26 +38,19 @@ export class ViewModelImpl<
3538
extends ViewModelBase<Payload, ParentViewModel>
3639
implements ViewModel<Payload, ParentViewModel>
3740
{
38-
constructor(
39-
protected rootStore: RootStore,
40-
params: ViewModelParams<Payload, ParentViewModel>,
41-
) {
42-
super(params);
43-
}
41+
trackName = new Date().toISOString()
4442
45-
// example of your custom methods
46-
// and properties
47-
get queryParams() {
48-
return this.rootStore.router.queryParams.data;
43+
getTrackTime() {
44+
return new Date();
4945
}
5046
}
5147
5248
```
5349

5450

55-
1. Make your own `ViewModelStore` implementation with accepting `RootStore` as `constructor` parameter and overriding `createViewModel` method for transfer `rootStore`
51+
1. Make your own `ViewModelStore` implementation
5652

57-
```ts{8,11,22,23,24}
53+
```ts{8,19,20,21}
5854
// view-model.store.impl.ts
5955
import {
6056
ViewModelParams,
@@ -65,10 +61,6 @@ import {
6561
import { ViewModelImpl } from "./view-model.impl.ts"
6662
6763
export class ViewModelStoreImpl extends ViewModelStoreBase {
68-
constructor(protected rootStore: RootStore) {
69-
super();
70-
}
71-
7264
createViewModel<VM extends ViewModel<any, ViewModel<any, any>>>(
7365
config: ViewModelCreateConfig<VM>,
7466
): VM {
@@ -77,7 +69,9 @@ export class ViewModelStoreImpl extends ViewModelStoreBase {
7769
// here is you sending rootStore as
7870
// first argument into VM (your view model implementation)
7971
if (ViewModelImpl.isPrototypeOf(VM)) {
80-
return new VM(this.rootStore, config);
72+
const instance = super.createViewModel(config) as unknown as ViewModelImpl;
73+
console.log(intance.getTrackTime());
74+
return instance;
8175
}
8276
8377
// otherwise it will be default behaviour
@@ -87,22 +81,7 @@ export class ViewModelStoreImpl extends ViewModelStoreBase {
8781
}
8882
```
8983

90-
3. Add `ViewModelStore` into your `RootStore`
91-
92-
```ts{8}
93-
import { ViewModelStore } from 'mobx-view-model';
94-
import { ViewModelStoreImpl } from '@/shared/lib/mobx';
95-
96-
export class RootStoreImpl implements RootStore {
97-
viewModels: ViewModelStore;
98-
99-
constructor() {
100-
this.viewModels = new ViewModelStoreImpl(this);
101-
}
102-
}
103-
```
104-
105-
4. Create `View` with `ViewModel`
84+
3. Create `View` with `ViewModel`
10685

10786
```tsx{2,4,10}
10887
import { ViewModelProps, withViewModel } from 'mobx-view-model';
@@ -114,7 +93,7 @@ export class MyPageVM extends ViewModelImpl {
11493
11594
async mount() {
11695
// this.isMounted = false;
117-
await this.rootStore.beerApi.takeBeer();
96+
console.log(this.trackName)
11897
super.mount(); // this.isMounted = true
11998
}
12099
@@ -133,3 +112,5 @@ const MyPageView = observer(({ model }: ViewModelProps<MyPageVM>) => {
133112
134113
export const MyPage = withViewModel(MyPageVM)(MyPageView);
135114
```
115+
116+
Also you may be helpful to read [**this recipe about integration with `RootStore`**](/recipes/integration-with-root-store)

docs/introduction/usage/with-base-implementation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const MyPageView = observer(({ model }: ViewModelProps<MyPageVM>) => {
4141
return <div>{model.state}</div>;
4242
});
4343

44-
export const MyPage = withViewModel(MyPageVM)(MyPageView);
44+
export const MyPage = withViewModel(MyPageVM, MyPageView);
4545
```
4646

4747
or you can use [`useCreateViewModel()` hook](/react/api/use-create-view-model)
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Integration with `RootStore`
2+
3+
This recipe may be helpful if you need to get access to your `RootStore` inside your `ViewModel` implementations
4+
5+
Follow the steps:
6+
7+
1. Make your own `ViewModel` implementation with accepting `RootStore` as `constructor` parameter
8+
9+
```ts
10+
// view-model.ts
11+
// interface for your view model
12+
import { ViewModel as ViewModelBase } from 'mobx-view-model';
13+
14+
export interface ViewModel<
15+
Payload extends AnyObject = EmptyObject,
16+
ParentViewModel extends ViewModel<any> = ViewModel<any, any>,
17+
> extends ViewModelBase<Payload, ParentViewModel> {}
18+
```
19+
20+
```ts{6,16}
21+
// view-model.impl.ts
22+
// implementation for your interface
23+
import { ViewModelBase, ViewModelParams } from 'mobx-view-model';
24+
25+
import { ViewModel } from './view-model';
26+
import { RootStore } from "@/shared/store";
27+
28+
export class ViewModelImpl<
29+
Payload extends AnyObject = EmptyObject,
30+
ParentViewModel extends ViewModel<any> = ViewModel<any>,
31+
>
32+
extends ViewModelBase<Payload, ParentViewModel>
33+
implements ViewModel<Payload, ParentViewModel>
34+
{
35+
constructor(
36+
protected rootStore: RootStore,
37+
params: ViewModelParams<Payload, ParentViewModel>,
38+
) {
39+
super(params);
40+
}
41+
42+
// example of your custom methods
43+
// and properties
44+
get queryParams() {
45+
return this.rootStore.router.queryParams.data;
46+
}
47+
}
48+
49+
```
50+
51+
52+
1. Make your own `ViewModelStore` implementation with accepting `RootStore` as `constructor` parameter and overriding `createViewModel` method for transfer `rootStore`
53+
54+
```ts{8,9,12,23,24,25}
55+
// view-model.store.impl.ts
56+
import {
57+
ViewModelParams,
58+
ViewModelStoreBase,
59+
ViewModel,
60+
ViewModelCreateConfig,
61+
} from 'mobx-view-model';
62+
import { ViewModelImpl } from "./view-model.impl.ts"
63+
import { RootStore } from "@/shared/store";
64+
65+
export class ViewModelStoreImpl extends ViewModelStoreBase {
66+
constructor(protected rootStore: RootStore) {
67+
super();
68+
}
69+
70+
createViewModel<VM extends ViewModel<any, ViewModel<any, any>>>(
71+
config: ViewModelCreateConfig<VM>,
72+
): VM {
73+
const VM = config.VM;
74+
75+
// here is you sending rootStore as
76+
// first argument into VM (your view model implementation)
77+
if (ViewModelImpl.isPrototypeOf(VM)) {
78+
return new VM(this.rootStore, config);
79+
}
80+
81+
// otherwise it will be default behaviour
82+
// of this method
83+
return super.createViewModel(config);
84+
}
85+
}
86+
```
87+
88+
3. Add `ViewModelStore` into your `RootStore`
89+
90+
```ts{8}
91+
import { ViewModelStore } from 'mobx-view-model';
92+
import { ViewModelStoreImpl } from '@/shared/lib/mobx';
93+
94+
export class RootStoreImpl implements RootStore {
95+
viewModels: ViewModelStore;
96+
97+
constructor() {
98+
this.viewModels = new ViewModelStoreImpl(this);
99+
}
100+
}
101+
```
102+
103+
4. Create `View` with `ViewModel`
104+
105+
```tsx{2,4,10}
106+
import { ViewModelProps, withViewModel } from 'mobx-view-model';
107+
import { ViewModelImpl } from '@/shared/lib/mobx';
108+
109+
export class MyPageVM extends ViewModelImpl {
110+
@observable
111+
accessor state = '';
112+
113+
async mount() {
114+
// this.isMounted = false;
115+
await this.rootStore.beerApi.takeBeer();
116+
super.mount(); // this.isMounted = true
117+
}
118+
119+
didMount() {
120+
console.info('did mount');
121+
}
122+
123+
unmount() {
124+
super.unmount();
125+
}
126+
}
127+
128+
const MyPageView = observer(({ model }: ViewModelProps<MyPageVM>) => {
129+
return <div>{model.state}</div>;
130+
});
131+
132+
export const MyPage = withViewModel(MyPageVM, MyPageView);
133+
```

0 commit comments

Comments
 (0)