Bobril框架入门指南

Bobril是一个由GMC Software Technology的软件架构师和开发者Boris Letocha编写的面向组件的前端框架。本文将介绍如何使用Bobril框架进行路由管理、组件定义和状态管理。

环境准备

要开始使用Bobril,首先需要在计算机上安装bobril-build。请按照中的步骤进行bobril-build的安装。安装完成后,可以开始一个新的项目,或者使用bobril-build GitHub仓库中的预定义骨架simpleApp。本文将使用后者作为示例。要获取最终代码,请下载完整的示例。

定义路由

Bobril提供了几种定义应用程序路由树的方法:

  • b.route - 定义路由URL、名称、处理器和子路由列表
  • b.routes - 将路由注册到应用程序并调用b.init
  • b.routeDefault - 如果当前URL中没有指定子路由,则定义默认路由

以下是一个在app.ts中定义路由的示例: import * as b from 'bobril'; import { mainPage } from './page'; import { pageOne } from './pages/pageOne'; import { pageTwo } from './pages/pageTwo'; b.routes( b.route({ handler: mainPage }, [ b.route({ url: '/one', name: 'one', handler: pageOne }), b.route({ url: '/two/:text?', name: 'two', handler: pageTwo }), b.routeDefault({ handler: pageOne }) ]) ); 整个应用程序将由处理器mainPage处理,子路由onetwo分别在URL'/one''/two'上由处理器pageOnepageTwo处理。如果没有指定子路由,将使用默认处理器pageOne

页面two的URL在第二个斜杠后面包含一个参数规范。它由冒号和一个参数名称定义。问号定义参数为可选。然后可以在处理器的上下文中的ctx.data.routeParams找到路由参数。

页面中的路由处理

现在,需要定义mainPage以渲染一些自己的内容和当前激活子路由的视觉内容。为此,将使用组件ctx.data.activeRouteHandler提供的函数,因此可以将page.ts的代码更改如下: import * as b from 'bobril'; export const mainPage = b.createComponent({ render(_ctx: b.IBobrilCtx, me: b.IBobrilNode): void { me.children = [ tag('h1', '路由示例'), tag('hr'), tag('div', me.data.activeRouteHandler()), ]; } }); 这段代码将渲染一个标题、一条线和当前激活子路由的视觉内容。

现在,需要定义子页面和这些页面之间的过渡。Bobril提供了以下函数和接口用于这些目的:

  • b.IRouteTransition - 过渡定义的接口(目标名称、参数等)
  • b.createRedirectReplace - 创建不保存历史的IRouteTransition对象进行重定向
  • b.createRedirectPush - 创建保存历史的IRouteTransition对象进行重定向
  • b.runTransition - 根据输入的IRouteTransition对象运行过渡
  • b.link - 将输入的IBobrilNode更改为指定名称的路由链接,并带有可选的参数

从页面one到页面two的重定向定义示例在pages/pageOne.ts中: import * as b from 'bobril'; import { textbox } from '../components/textbox'; import { button } from '../components/button'; let value = ''; export const pageOne = b.createComponent({ render(ctx: b.IBobrilCtx, me: b.IBobrilNode): void { me.children = [ textbox({ value, onChange: (newVal) => { value = newVal; b.invalidate(ctx); } }), button({ title: '确认', onClick: () => { b.runTransition(b.createRedirectPush('two', { text: value })); return true; } }) ]; } }); 按钮的onClick回调创建并运行一个过渡到页面two,定义了一个包含text参数值的对象。

上面的过渡必须由在pages/pageTwo.ts中定义的pageTwo处理器处理: import * as b from 'bobril'; import { tag } from '../helper'; import { loggedIn } from '../page'; export interface IData { routeParams: { text?: string }; } export interface ICtx extends b.IBobrilCtx { data: IData; } export const pageTwo = b.createComponent({ render(ctx: ICtx, me: b.IBobrilNode): void { let value = (ctx.data.routeParams.text || '').trim(); me.children = [ tag('p', '文本: ' + (!!value ? value : '无')), b.link(tag('a', '返回'), 'one') ]; } }); 页面在其ctx.data.routeParams.text中接收text参数值,因此可以指定上下文和数据接口,并在页面组件render函数中使用text。它还通过函数b.link定义了一个到页面one的链接节点。

过渡可用性

有时需要管理当前页面在当前路由上是否可用,或者否可以离开当前页面。为此,可以使用IBobrilComponent的以下静态函数:

  • canActivate - 它可以通过返回false来阻止目标处理器中的当前过渡,或者重定向到新指定的过渡
  • canDeactivate - 可以通过返回false来阻止源处理器中的当前过渡,或者重定向到新指定的过渡

例如,可以通过在pages/pageOne.ts中的页面one组件定义中添加canDeactivate函数定义来处理带有空textbox值的页面离开: canDeactivate() { return !!value.trim() || confirm('文本框为空。确定要离开吗?'); } 或者通过在pages/pageTwo.ts中的页面two组件定义中添加canActivate函数定义来处理未登录用户访问页面: canActivate() { if (loggedIn) return true; alert('未登录!'); return b.createRedirectReplace('one'); } 注意:loggedIn变量在mainPage中声明和设置,并导入到pageTwo。请参阅附带的full sample中的page.ts

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485