1- // 核心实例对象, 接收配置, 文件以及node信息\
1+ // 核心实例对象, 接收配置, 文件以及node信息
22import {
33 Subscribe ,
44 webRequest
@@ -22,85 +22,148 @@ import { LowCodeNode } from './node';
2222import Flexible from './flexible' ;
2323import { defaultTransformStyle } from './utils' ;
2424
25+ /**
26+ * 应用配置选项接口
27+ */
2528interface IAppOptionsConfig {
26- config ?: ISchemasRoot ;
27- designWidth ?: number ;
28- ua ?: string ;
29- curPage ?: Id ;
30- platform ?: 'mobile' | 'pc' ;
31- disabledFlexible ?: boolean ;
32- transformStyle ?: ( style : Record < string , any > ) => Record < string , any > ;
33- request ?: IRequestFunction ;
34- useMock ?: boolean ;
29+ config ?: ISchemasRoot ; // DSL配置数据
30+ designWidth ?: number ; // 设计稿宽度
31+ ua ?: string ; // 用户代理字符串
32+ curPage ?: Id ; // 当前页面ID
33+ platform ?: 'mobile' | 'pc' ; // 平台类型
34+ disabledFlexible ?: boolean ; // 是否禁用移动端适配
35+ transformStyle ?: ( style : Record < string , any > ) => Record < string , any > ; // 样式转换函数
36+ request ?: IRequestFunction ; // 自定义请求函数
37+ useMock ?: boolean ; // 是否使用Mock数据
3538}
3639
40+ /**
41+ * 低代码应用核心类
42+ * 负责管理整个低代码应用的生命周期、页面切换、组件注册、事件处理等核心功能
43+ */
3744export class LowCodeRoot extends Subscribe implements ILowCodeRoot {
45+ /** 环境信息对象,包含设备、浏览器等信息 */
3846 public env : Env = new Env ( ) ;
39- public schemasRoot ?: ISchemasRoot ; // dsl
47+
48+ /** DSL配置根对象 */
49+ public schemasRoot ?: ISchemasRoot ;
50+
51+ /** 当前页面实例 */
4052 public page ?: LowCodePage ;
53+
54+ /** 平台类型,默认为移动端 */
4155 public platform = 'mobile' ;
56+
57+ /** 组件注册表,存储所有注册的组件 */
4258 public components = new Map ( ) ;
59+
60+ /** 网络请求函数 */
4361 public request ?: IRequestFunction ;
62+
63+ /** 数据源管理器 */
4464 public dataSourceManager ?: DataSourceManager ;
65+
66+ /** 是否使用Mock数据 */
4567 public useMock = false ;
68+
69+ /** 移动端适配实例 */
4670 private flexible ?: Flexible ;
71+
72+ /** 样式转换函数 */
4773 public transformStyle : ( style : Record < string , any > ) => Record < string , any > ;
4874
75+ /** 事件映射表,存储所有注册的事件处理函数 */
4976 private eventMap = new Map ( ) ;
5077
78+ /**
79+ * 构造函数
80+ * @param options 应用配置选项
81+ */
5182 constructor ( options : IAppOptionsConfig ) {
5283 super ( ) ;
5384
85+ // 设置环境信息
5486 this . setEnv ( options . ua ) ;
87+
88+ // 设置平台类型
5589 options . platform && ( this . platform = options . platform ) ;
90+
91+ // 初始化移动端适配
5692 this . flexible = new Flexible ( { designWidth : options . designWidth } ) ;
93+
94+ // 设置DSL配置
5795 if ( options . config ) {
5896 this . setConfig ( options . config , options . curPage ) ;
5997 }
98+
99+ // 设置网络请求函数
60100 if ( options . request ) {
61101 this . request = options . request ;
62102 } else if ( typeof globalThis . fetch === 'function' ) {
103+ // 如果浏览器支持fetch,使用默认的webRequest
63104 this . request = webRequest ;
64105 }
106+
107+ // 设置样式转换函数
65108 this . transformStyle = options . transformStyle || ( ( style : Record < string , any > ) => defaultTransformStyle ( style , this . flexible ?. designWidth ) ) ;
66109 }
67110
111+ /**
112+ * 设置环境信息
113+ * @param ua 用户代理字符串
114+ */
68115 public setEnv ( ua ?: string ) {
69116 this . env = new Env ( ua ) ;
70117 }
71118
72119 /**
73- * 设置schemas
74- * @param config ISchemasRoot
120+ * 设置DSL配置
121+ * @param config ISchemasRoot DSL根配置对象
75122 * @param curPage 当前页面id
76123 */
77124 public setConfig ( config : ISchemasRoot , curPage ?: Id ) {
78125 this . schemasRoot = config ;
79126
127+ // 如果没有指定当前页面,默认使用第一个页面
80128 if ( ! curPage && config . children . length ) {
81129 curPage = config . children [ 0 ] ! . field ;
82130 }
83131
132+ // 销毁之前的数据源管理器
84133 if ( this . dataSourceManager ) {
85134 this . dataSourceManager . destroy ( ) ;
86135 }
87136
137+ // 清除之前注册的事件
88138 this . removeEvents ( ) ;
89139
140+ // 创建新的数据源管理器
90141 this . dataSourceManager = createDataSourceManager ( this , this . useMock ) ;
91142
143+ // 设置当前页面
92144 this . setPage ( curPage || this . page ?. data ?. field ) ;
93145
146+ // 处理页面描述信息(标题、关键词、描述等)
94147 this . dealDescribe ( config ) ;
95148 }
96149
150+ /**
151+ * 处理页面描述信息,设置页面标题和meta标签
152+ * @param config DSL根配置对象
153+ */
97154 private dealDescribe ( config : ISchemasRoot ) {
155+ // 确保在浏览器环境中才执行DOM操作
98156 if ( globalThis && globalThis . document ) {
157+ // 设置页面标题
99158 globalThis . document . title = config . name ;
159+
160+ // 清除现有的meta标签
100161 const metaTags = globalThis . document . getElementsByTagName ( 'meta' ) ;
101162 while ( metaTags . length > 0 ) {
102163 metaTags [ 0 ] ?. parentNode ?. removeChild ( metaTags [ 0 ] ) ;
103164 }
165+
166+ // 设置新的meta标签
104167 if ( config . description ) {
105168 config . description . keywords &&
106169 this . setDescribe ( config . description , 'keywords' ) ;
@@ -110,9 +173,15 @@ export class LowCodeRoot extends Subscribe implements ILowCodeRoot {
110173 }
111174 }
112175
176+ /**
177+ * 设置页面meta描述信息
178+ * @param describe 描述对象
179+ * @param key 描述类型(keywords 或 description)
180+ */
113181 private setDescribe ( describe : IMetaDes , key : 'keywords' | 'description' ) {
114182 const header = globalThis . document . getElementsByTagName ( 'head' ) [ 0 ] ;
115183 if ( describe && describe [ key ] . length > 0 ) {
184+ // 为每个描述项创建meta标签
116185 for ( const str of describe [ key ] ) {
117186 const metaTags = globalThis . document . createElement ( 'meta' ) ;
118187 metaTags . name = key ;
@@ -123,12 +192,16 @@ export class LowCodeRoot extends Subscribe implements ILowCodeRoot {
123192 }
124193
125194 /**
126- * 设置当前展示页
195+ * 设置当前展示页面
196+ * @param field 页面标识符
127197 */
128198 public setPage ( field ?: Id ) {
199+ // 查找指定的页面配置
129200 const pageConfig = this . schemasRoot ?. children . find (
130201 ( page ) => page . field === field
131202 ) ;
203+
204+ // 如果找不到页面配置,清空当前页面
132205 if ( ! pageConfig ) {
133206 if ( this . page ) {
134207 this . page . destroy ( ) ;
@@ -138,21 +211,25 @@ export class LowCodeRoot extends Subscribe implements ILowCodeRoot {
138211 return ;
139212 }
140213
214+ // 如果是同一个页面,不需要重新创建
141215 if ( pageConfig === this . page ?. data ) return ;
142216
217+ // 销毁旧页面
143218 if ( this . page ) {
144219 this . page . destroy ( ) ;
145220 }
146221
222+ // 创建新页面实例
147223 this . page = new LowCodePage ( { config : pageConfig , root : this } ) ;
224+
225+ // 触发页面切换事件
148226 super . emit ( 'page-change' , this . page ) ;
149- // this.bindEvents();
150227 }
151228
152229 /**
153- * 查询页面
154- * @param id 节点id
155- * @returns Page | void
230+ * 查询页面实例
231+ * @param field 页面标识符,不传则返回当前页面
232+ * @returns Page实例或undefined
156233 */
157234 public getPage ( field ?: Id ) {
158235 if ( ! field ) return this . page ;
@@ -161,15 +238,25 @@ export class LowCodeRoot extends Subscribe implements ILowCodeRoot {
161238 }
162239 }
163240
241+ /**
242+ * 删除当前页面
243+ */
164244 public deletePage ( ) {
165245 this . page = undefined ;
166246 }
167247
248+ /**
249+ * 设置设计稿宽度
250+ * @param width 设计稿宽度
251+ */
168252 public setDesignWidth ( width : number ) {
169253 this . flexible ?. setDesignWidth ( width ) ;
170254 }
171255
172- // TODO 增加设备判断
256+ /**
257+ * 判断是否为移动端设备
258+ * @returns boolean
259+ */
173260 public isH5 ( ) {
174261 return (
175262 this . env . isAndroid ||
@@ -181,87 +268,110 @@ export class LowCodeRoot extends Subscribe implements ILowCodeRoot {
181268 ) ;
182269 }
183270
184- // 设置body字体大小
185-
271+ /**
272+ * 发送事件
273+ * 重写父类的emit方法,支持组件级别的事件命名空间
274+ * @param name 事件名称
275+ * @param args 事件参数
276+ */
186277 public override emit ( name : string , ...args : any [ ] ) {
187278 const [ node , ...otherArgs ] = args ;
188- // 由于组件可能有很多个, 所以组件事件需要加入id来区分
279+ // 如果第一个参数是节点实例,为事件名添加节点ID前缀以区分不同组件的同名事件
189280 if ( node && node instanceof LowCodeNode && node ?. data ?. field ) {
190281 super . emit ( `${ node . data . field } :${ name } ` , node , ...otherArgs ) ;
191282 }
192283 super . emit ( name , ...args ) ;
193284 }
194285
195- // 将事件注册为全局事件
196- // TODO: 目前是将所有的事件(未使用, 已使用)全部注册, 后续会优化此部分逻辑, 只注册已使用到的, 优化性能
286+ /**
287+ * 注册全局事件
288+ * 将事件函数包装后注册到事件系统中
289+ * @param key 事件键名
290+ * @param fn 事件处理函数
291+ * @param ds 数据源实例
292+ * @param node 节点实例(可选,用于组件事件)
293+ */
197294 public registerEvent (
198295 key : string ,
199296 fn : Fn ,
200297 ds ?: DataSource ,
201298 node ?: LowCodeNode
202299 ) {
300+ // 包装事件处理函数,注入app和dataSource参数
203301 const eventHanlder = ( ...args : any [ ] ) => {
204302 fn ( { app : this , dataSource : ds || { } } , ...args ) ;
205303 } ;
206- // 先清空
304+
305+ // 如果事件已存在,先移除旧的
207306 if ( this . cache . has ( key ) ) {
208307 this . remove ( key ) ;
209308 }
309+
310+ // 如果是组件事件,添加组件ID前缀
210311 if ( node ) {
211- // 组件事件
212312 key = `${ node . data . field } :${ key } ` ;
213313 }
314+
315+ // 存储事件处理函数并注册
214316 this . eventMap . set ( key , eventHanlder ) ;
215317 this . on ( key , eventHanlder ) ;
216318 }
217319
218- // public async dataSourceActionHandler() {
219- // }
220-
221320 /**
222- * 移除所有事件
321+ * 移除所有注册的事件
223322 */
224323 public removeEvents ( ) {
225- // 先移除所有事件
324+ // 遍历所有注册的事件并移除
226325 Array . from ( this . eventMap . keys ( ) ) . forEach ( ( key ) => {
227326 const events = this . eventMap . get ( key ) ;
228327 events && this . remove ( key ) ;
229328 } ) ;
329+
330+ // 清空事件映射表
230331 this . eventMap . clear ( ) ;
231332
232333 if ( ! this . page ) return ;
233334 }
234- /**
235- * 事件联动处理函数
236- */
237- // private async eventHandler() {
238-
239- // }
240335
241336 /**
242337 * 注册组件
338+ * @param type 组件类型名称
339+ * @param comp 组件实例或组件类
243340 */
244341 public registerComponent ( type : string , comp : any ) {
245342 this . components . set ( type , comp ) ;
246343 }
247344
248345 /**
249- * 删除组件
346+ * 注销组件
347+ * @param type 组件类型名称
250348 */
251349 public unregisterComponent ( type : string ) {
252350 this . components . delete ( type ) ;
253351 }
254352
353+ /**
354+ * 解析获取组件
355+ * @param type 组件类型名称
356+ * @returns 组件实例或组件类
357+ */
255358 public resolveComponent ( type : string ) {
256359 return this . components . get ( type ) ;
257360 }
258361
362+ /**
363+ * 销毁应用实例
364+ * 清理所有资源,包括事件、页面、适配器等
365+ */
259366 public destroy ( ) {
367+ // 清理事件订阅
260368 this . clear ( ) ;
369+
370+ // 清理页面实例
261371 this . page = undefined ;
372+
373+ // 销毁移动端适配器
262374 this . flexible ?. destroy ( ) ;
263375 this . flexible = undefined ;
264- // if (this.isH5()) {
265- // }
266376 }
267377}
0 commit comments