BobX框架与Bobril应用开发指南

在现代Web开发中,状态管理是构建可维护和可扩展应用的关键部分。BobX是一个类似于MobX的库,专为Bobril应用设计,用于管理应用的状态。BobX由Boris Letocha(Quadient)开发,使用TypeScript编写,非常适合Bobril应用的需求。它采用观察者模式,其中状态(stores)是可观察的主题,而Bobril组件则是观察者。

BobX入门

将通过创建一个简单的TODO应用来开始。首先,确保计算机上已经安装了Bobril构建工具。按照第一篇文章中的步骤进行安装。现在,可以开始一个新的项目,或者使用来自Bobril构建工具GitHub仓库的预定义骨架simpleApp。

以下示例将使用simpleApp。要获取包括所有所需组件的最终代码,请下载完整的示例代码。

BobX应用架构

BobX使用TypeScript的实验性特性——装饰器。要允许使用装饰器,请在package.json文件的bobril/compilerOptions部分添加以下参数: { "bobril": { "compilerOptions": { "experimentalDecorators": true } } }

接下来,将BobX添加到应用中: npm i bobx --save

创建BobX状态管理

首先,将创建一个简单的BobX状态管理,它包含与Bobflux变体相同的数据。这个状态管理将在store.ts文件中定义: import { observable } from 'bobx'; class TodoStore { @observable todoName: string = ''; @observable private _todos: string[] = []; get todos(): string[] { return this._todos; } addTodo(): void { if (this.todoName.trim().length === 0) return; this._todos.push(this.todoName.trim()); this.todoName = ''; } } export const todoStore = new TodoStore();

在上面的代码中,使用了@observable装饰器来创建todoName和_todos字段的getter/setter,并跟踪这些字段。当这些字段在Bobril组件的任何渲染函数中使用时,将自动调用b.invalidate(ctx)函数,更新特定的上下文。

使用BobX构建页面

现在,已经准备好在TODO应用的页面上使用BobX了。src/mainPage.ts文件将如下所示: import * as b from 'bobril'; import { button } from './components/button'; import { textbox } from './components/textbox'; import { p } from './components/paragraph'; import { h1 } from './components/header'; import { todoStore } from './store'; export const mainPage = b.createComponent({ render(_ctx: b.IBobrilCtx, me: b.IBobrilNode): void { me.children = [ h1({}, 'TODO'), p({}, [ textbox({ value: todoStore.todoName, onChange: newValue => todoStore.todoName = newValue }), button({ title: 'ADD', onClick: () => todoStore.addTodo() }) ]), todoStore.todos.map(item => p({}, item)), p({}, `Count: ${todoStore.todos.length}`) ]; } });

组件的定义不是本文的主题,因此可以使用附带的源代码中的定义。可以看到页面直接从store模块导入状态管理。textbox和button组件在其onChange和onClick回调中使用状态管理中定义的操作,以便视图中的用户交互触发操作调用。最后,在render函数的末尾是一个映射的todos数组,用于显示待办事项名称。

全局状态管理

全局状态管理是定义和使用状态的一种方式,但不是唯一的方式。可以在组件的init方法中直接实例化页面状态,并将其通过数据传递给其子组件。也可以为组件的内部数据创建上下文状态,这些数据想要跟踪。

上下文状态的示例: class CtxStore extends b.BobrilCtx { @observable someProperty: string = ''; constructor(data: IData, me: b.IBobrilCacheNode) { super(data, me); ... } } export const myComponent = b.createComponent({ ctxClass: CtxStore, render(ctx: CtxStore) { ... } });

状态优化

除了纯粹的observable函数来定义可观察属性外,有时不想跟踪对象的所有属性。让来看看其他可能的方式:

  • observable.deep - 默认的observable方式。它递归地装饰给定对象的所有定义属性,使其可观察(跟踪)。当属性包含具有定义原型的对象时,递归停止。
  • observable.ref - 只跟踪对象的引用。内部属性的任何更改都不会触发渲染。
  • observable.shallow - 这种变体将跟踪给定对象的引用、其属性,但不会跟踪更多。例如,数组将跟踪其引用、其内容,但不会跟踪其项的内容。
  • observable.map - 可以使用这个函数创建一个动态键控的可观察映射。
  • computed - 可以在类属性的任何getter上使用这个装饰器,以声明性地创建计算属性。计算值是可以从未有状态或其他计算值派生的值。
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485