Bobril-VI-BobX应用程序商店管理
BobX是类似于MobX的库,用于管理由BorisLetocha(Quadient)创建的应用程序商店。它是用TypeScript编写的,适合bobril应用程序的需求。它使用观察者模式,其中存储是可观察的主题,而小商品成分是观察者。
开始吧
我们将再次创建一个简单的TODO应用程序。首先,我们需要bobril-build在计算机上进行准备。请按照第一篇文章中的步骤执行bobril-build安装。
现在,你可以重新开始一个新项目或使用预定义的骨架simpleApp从bobril建造的github仓库。
以下示例将使用它。要获取包括所有必需组件的最终代码,请下载完整的示例。
BobX使用TypeScript的实验功能-装饰器。要允许使用装饰器,请将以下参数添加到package.json的bobril/compilerOptions部分:
"bobril": { "compilerOptions": { "experimentalDecorators": true } }12345复制代码类型:[html]
将bobx添加到应用程序
在应用程序文件夹的根目录中运行以下命令:
npm i npm i bobx --save bb123复制代码类型:[html]
店铺
首先,我们将创建一个简单的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();12345678910111213141516171819复制代码类型:[html]
在上面的代码中,您可以看到@observable在字段todoName和上使用了修饰符_todos。该修饰器在这些字段上创建具有跟踪功能的吸气剂/吸气剂。它将导致对这些字段的跟踪。当在bobril组件节点中的任何渲染函数中使用此类字段时,该函数b.invalidate(ctx)将自动调用,具体context取决于此字段的每次更改。
用BobX组成页面
现在,我们已经准备好在todo应用程序页面上使用的所有内容。在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}`) ]; } });123456789101112131415161718192021复制代码类型:[html]
组件定义不是本文的主题,因此您可以在随附的源代码中使用定义。
您可以看到页面直接从store模块导入商店。
在textbox和button组件使用规定的行为store在他们onChange并onClick因此从视图中的用户交互发起行动的呼声回调。最后,在render函数的最后是p待办事项到带有待办事项名称的''标签的映射数组。
现在,我们可以在http://localhost:8080的浏览器中打开该应用程序,并查看其工作方式。
Global存储是定义和使用存储的一种方法,但不是唯一的方法。
Page存储可以直接在init组件方法中实例化,并通过数据提供给其子组件。
在上下文存储设备可以为您要跟踪的组件内数据的组件上下文中创建。
上下文存储示例:
class CtxStore extends b.BobrilCtx<IData> { @observable someProperty: string = ''; constructor(data: IData, me: b.IBobrilCacheNode) { super(data, me); ... } } export const myComponent = b.createComponent<IData>({ ctxClass: CtxStore, render(ctx: CtxStore) { ... } })123456789101112131415复制代码类型:[html]
商店优化
不仅存在observable定义可观察属性的纯函数。有时,您不想跟踪对象的所有属性,因此让我们看一下其他可能的方法:
observable.deep-默认observable方式。它装饰了给定对象的所有定义的属性,以使其可以递归地进行观察(跟踪)。当属性包含定义了原型的对象时,递归停止。
observable.ref-仅跟踪对象的参考。内部属性的任何更改都不会触发渲染。
observable.shallow-此变体将跟踪给定对象的引用,其属性,但仅此而已。因此,例如,将跟踪该数组以获取其引用,其内容,而不跟踪其项的内容。
observable.map-您可以使用此功能创建动态键控的可观察地图。
computed-您可以在类属性的任何获取器上使用此装饰器,以声明方式创建计算属性。计算值是可以从现有商店中得出的值或其他计算值。