Skip to content

Commit

Permalink
docs: store-bean
Browse files Browse the repository at this point in the history
  • Loading branch information
zhennann committed Oct 3, 2024
1 parent 9b99e2a commit f4a2a72
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 94 deletions.
71 changes: 24 additions & 47 deletions zova-docs/guide/essentials/ioc/store-bean.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ Through store bean, we can define a global state object and use it in any module

## Create Store Bean: userInfo

Let's first create a store bean `userInfo`. The code skeleton for store bean can be created using the cli command:
::: tip
Context Menu - [Module Path/src]: `Zova Create/Bean: Store`
:::

```bash
$ zova :create:store userInfo --module=demo-basic
```
Enter the name of store bean according to the prompt, such as `userInfo`. The VSCode extension will automatically add the code skeleton of `store bean`

`src/suite/a-demo/modules/demo-basic/src/bean/store.userInfo.ts`

Expand All @@ -27,12 +27,13 @@ export class StoreUserInfo {}

We add a reactive property `user` in `userInfo` and perform asynchronous initialization

```typescript{1-4,7-23}
```typescript{1-4,8-24}
interface User {
name: string;
age: number;
}
@Store()
export class StoreUserInfo {
user: User;
Expand All @@ -56,20 +57,15 @@ export class StoreUserInfo {

## Use Store Bean

Next, create local bean `testC` using the cli command:

```bash
$ zova :create:local testC --module=demo-basic
```

Then inject `userInfo` directly into `testC` and access the properties and methods of `userInfo`
Then inject `userInfo` directly into the page component `counter`, and access the properties and methods of `userInfo`

`src/suite/a-demo/modules/demo-basic/src/testC.ts`
`src/suite/a-demo/modules/demo-basic/src/page/counter/controller.ts`

```typescript{1,4-5,8-9}
import { StoreUserInfo } from './bean/store.userInfo.js';
```typescript{1,5-6,9-10}
import { StoreUserInfo } from '../../bean/store.userInfo.js';
export class TestC {
@Local()
export class ControllerPageCounter {
@Use()
$$userInfo: StoreUserInfo;
Expand All @@ -80,45 +76,22 @@ export class TestC {
}
```

- By the property decorated with `Use`, the system will automatically look up or create an instance in the app bean container, and then inject it into `testC`
- By the property decorated with `Use`, the system will automatically look up or create an instance in the app bean container, and then inject it into the page component
- Set the type of `$$userInfo` to `StoreUserInfo`, the app bean container will find the class and create an instance based on this type

## Use Store Bean Cross-Module

What we just demonstrated was using store beans within the current module. Now let's take a look at how to use them cross-module

### Bean Identifier
Assume that we create another module `demo-basic2` and create a page component `counter2` in the module, then the code using Store Bean is as follows:

In Zova, a module is a natural bundle boundary, and automatically bundled into an independent asynchronous chunk when building

Therefore, when using store beans cross-module, we do not recommend injecting directly based on `type`, but rather on `identifier`

The system will automatically assign an identifier to each store bean as the following format:

```bash
{moduleName}.store.{beanName}
```
`src/suite/a-demo/modules/demo-basic2/src/page/counter2/controller.ts`

For example, the previously created `userInfo` corresponds to the identifier `demo-basic.store.userInfo`, where `demo-basic` is the module name which `userInfo` belongs to

### Use Store Bean

Next, create a module `a-demo2` using the cli command, and create a local bean `testD` at the same time:

```bash
$ zova :create:module a-demo2 --template=basic --suite=a-demo
$ pnpm install --force
$ zova :create:local testD --module=a-demo2
```

Then inject `userInfo` directly into `testD` and access the properties and methods of `userInfo`

`src/suite/a-demo/modules/a-demo2/src/testD.ts`

```typescript{1,4-5,8-9}
```typescript{1,5-6,9-10}
import { StoreUserInfo } from 'zova-module-demo-basic';
export class TestD {
@Local()
export class ControllerPageCounter {
@Use()
$$userInfo: StoreUserInfo;
Expand All @@ -129,5 +102,9 @@ export class TestD {
}
```

- Import the type of class `StoreUserInfo` from the module of `zova-module-demo-basic`
- The system will automatically look up or create an instance in the app bean container, and then inject it into `testD`
- Import class `StoreUserInfo` from the module of `zova-module-demo-basic`
- The system will automatically look up or create an instance in the app bean container, and then inject it into the page component

::: info
Based on the support of the compiler, Store Bean will automatically switch to asynchronous loading mode. Specifically, the system will asynchronously load the module `demo-basic`, then obtain class `StoreUserInfo`, and then look up or create an instance which will be injected into the page component
:::
70 changes: 23 additions & 47 deletions zova-docs/zh/guide/essentials/ioc/store-bean.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

## 创建Store Bean: userInfo

我们先来创建一个 store bean `userInfo`。可以通过 cli 命令创建 store bean 的代码骨架:
::: tip
右键菜单 - [模块路径/src]: `Zova Create/Bean: Store`
:::

```bash
$ zova :create:store userInfo --module=demo-basic
```
依据提示输入 store bean 的名称,比如`userInfo`,VSCode 插件会自动添加 store bean 的代码骨架

`src/suite/a-demo/modules/demo-basic/src/bean/store.userInfo.ts`

Expand Down Expand Up @@ -57,20 +57,15 @@ export class StoreUserInfo {

## 使用Store Bean

接下来通过 cli 命令创建一个 local bean `testC`

```bash
$ zova :create:local testC --module=demo-basic
```

然后直接在`testC`中注入`userInfo`,并访问其中的属性和方法
接下来,在页面组件`counter`中注入`userInfo`,并访问其中的属性和方法

`src/suite/a-demo/modules/demo-basic/src/testC.ts`
`src/suite/a-demo/modules/demo-basic/src/page/counter/controller.ts`

```typescript{1,4-5,8-9}
import { StoreUserInfo } from './bean/store.userInfo.js';
```typescript{1,5-6,9-10}
import { StoreUserInfo } from '../../bean/store.userInfo.js';
export class TestC {
@Local()
export class ControllerPageCounter {
@Use()
$$userInfo: StoreUserInfo;
Expand All @@ -81,45 +76,22 @@ export class TestC {
}
```

- 通过`Use`装饰器函数会自动在 app bean 容器中查找或者创建一个 store 实例,然后注入到`testC`
- 通过`Use`装饰器函数会自动在 app bean 容器中查找或者创建一个 store 实例,然后注入到页面组件中
-`$$userInfo`的类型设置为`StoreUserInfo`,app bean 容器将根据此类型找到 class 并创建一个实例

## 跨模块使用
## 跨模块使用Store Bean

刚才演示的是在当前模块中使用 store bean,现在我们看看如何跨模块使用

### Bean标识

在 Zova 中,一个模块就是一个天然的拆包边界,在 build 构建时,自动打包成一个独立的异步 Chunk

因此,在跨模块使用 store bean 时,我们不建议直接`基于类型`注入,而是`基于标识`注入

系统会为每一个 store bean 自动分配一个标识,格式如下:

```bash
{moduleName}.store.{beanName}
```

比如,前面创建的 `userInfo`,对应的标识为:`demo-basic.store.userInfo`,其中`demo-basic``userInfo`所归属的模块名称

### 跨模块使用Store Bean

接下来通过 cli 命令创建一个模块`a-demo2`,同时创建一个 local bean `testD`
假设我们又创建了一个模块`demo-basic2`,在模块中创建了一个页面组件`counter2`,那么使用 Store Bean 的代码如下:

```bash
$ zova :create:module a-demo2 --template=basic --suite=a-demo
$ pnpm install --force
$ zova :create:local testD --module=a-demo2
```

然后直接在`testD`中注入`userInfo`,并访问其中的属性和方法
`src/suite/a-demo/modules/demo-basic2/src/page/counter2/controller.ts`

`src/suite/a-demo/modules/a-demo2/src/testD.ts`

```typescript{1,4-5,8-9}
```typescript{1,5-6,9-10}
import { StoreUserInfo } from 'zova-module-demo-basic';
export class TestD {
@Local()
export class ControllerPageCounter {
@Use()
$$userInfo: StoreUserInfo;
Expand All @@ -130,5 +102,9 @@ export class TestD {
}
```

-`zova-module-demo-basic`模块导入 class `StoreUserInfo`的类型
- 系统会自动在 app bean 容器中查找或者创建一个 store 实例,然后注入到`testD`
-`zova-module-demo-basic`模块导入 class `StoreUserInfo`
- 系统会自动在 app bean 容器中查找或者创建一个 store 实例,然后注入到页面组件中

::: info
基于编译器的加持, Store Bean 会自动转为异步加载模式,具体而言就是:系统会异步加载模块`demo-basic`,然后取得 class `StoreUserInfo`,完成实例的查找、创建与注入
:::

0 comments on commit f4a2a72

Please sign in to comment.