# data-driven **Repository Path**: NoRainLand/data-driven ## Basic Information - **Project Name**: data-driven - **Description**: 一个用来实现以数据描述状态,通过数据变化驱动界面交互的框架。为的是更好更快地拼ui。用这个能取代事件系统,避免想大量事件名,避免漏写事件关闭导致的bug等等。另外还设置了数据更新模式,能够方便地控制计算的时间点,避免某些计算击中在一起导致的卡顿。 - **Primary Language**: TypeScript - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2022-05-24 - **Last Updated**: 2023-02-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # data-driven #### 介绍 一个用来实现以数据描述状态,通过数据变化驱动界面交互的框架。为的是更好更快地拼ui。用这个能取代事件系统,避免想大量事件名,避免漏写事件关闭导致的bug等等。另外还设置了数据更新模式,能够方便地控制计算的时间点,避免某些计算击中在一起导致的卡顿。 完全开源!有能力的尽管拿去魔改! 现在还刚刚完成,可能会有些问题,发现bug请联系我。 代码不多,但是前前后后断断续续改版了好多好多次,可以说是花了大量心血在里面,现在的模式感觉能用了,以后有时间还会考虑开发一个可视化编辑器出来,希望大家多多支持! 最后,愿所有ui仔拜托繁杂耦合的交互逻辑! #### 框架结构 ValueObject:这个类是我们的主角,通过将数据包装成vo,然后更快更好地定义数据之间的关系,通过框架底层实现“源头数据”变化后,定义好关系的“衍生数据”自动变化,从而取代事件系统 ValueObjectArray:ValueObject的数组版本,很多难搞但是又经常需要的功能封装在了这里。 EventDispatcher:事件分发器,事件系统还是用了一下下,不过是用在底层封装用的。 #### 使用说明 1. 基本用法 例如: let role = new ValueObject(["atk = 10", "hp = 100"]) // 角色的最终攻击力为基础攻击力+血量的20% role.bind("final_atk", "atk + hp * 0.2") role.atk = 15 console.log(role.final_atk) //此时应为35 role.hp = 1000 //此时应为215 2. vo数组用法,这就比较多了,现在主要封装了sum/max/avg方法(取数组中所有child的综合值),child(n)方法:索引第n个child,n为-1表示倒数第一个 let pets = new ValueObjectArray(null, ["hp = 10", "def = 3"], 10); console.log(pets[0].hp, pets[1].def); // 绑定角色属性和宠物的属性关系 let role = new ValueObject(["atk=10", "pets", "def=9"]); role.pets = pets; role.bind("final_atk", "pets.sum(hp)*0.1+atk"); role.bind("final_def", "pets.max(def)+def"); pets[7].def = 6; pets.push(new ValueObject(["hp=10", "def=10"])); console.log(role.final_atk); //输出21 console.log(role.final_def); //输出19 // 更改源头数据后,自动更新相应衍生数据 role.pets[3].hp = 100; role.pets[5].def = 34; console.log(role.final_atk); //输出30 console.log(role.final_def); //输出43 role.bind("star", "pets.length * 3"); console.log(role.star); pets.push(new ValueObject(["hp=11", "def=3"])); console.log(role.star); role.bind("firstPet", "pets.child(0)"); console.log(role.firstPet.hp); pets[0].hp = 34; console.log(role.firstPet.hp); pets[0] = new ValueObject(["hp=999", "def=123"]); console.log(role.firstPet.hp); console.log(role.final_atk); pets.insert(new ValueObject(["hp = 1999", "def = 199"]), 0); console.log(role.firstPet.hp); role.bind("secondPet", "pets.child(1)"); for (let i = 0; i < 10; i++) { pets.insert(new ValueObject(["hp = " + i, "def = 99"]), 0); console.log(role.secondPet.hp); } role.bind("lastPet", "pets.child(-1)"); console.log(role.lastPet.hp); for (let i = 0; i < 10; i++) { pets.push(new ValueObject(["hp = " + i, "def = 99"])); console.log(role.lastPet.hp); } 3. 数据更新模式 这套框架里定义了一个updatemode枚举变量,对每个vo的每个prop都可以设置。表示属性在什么时间点更新。 Immediately:立即更新 NextTick:下一帧更新 OnFree:空闲时更新 OnGet:获取时更新 默认为Immediately,有些数据不适合立即更新,比如会在一帧内频繁计算多次,并且计算出来的数据时用于界面显示的,完全可以放到下一帧去更新 3. 从数据变化到界面变化 需要根据具体使用的引擎封装一下,我之后会先封装一下cocos creator的一个组件出来。 大致封装方法(以cocos creator为例)如下: private _vo = new ValueObject(); setVo(vo: ValueObject) { this._vo = vo; } bindText(path: string, fml: string, mode: Update_mode = Update_mode.Immediately) { this._vo.bind(path + "_text", fml); this._vo.on(path + "_text", this._bindTextCb, this, path); } private _bindTextCb(_: string, value: any, path: string) { this.setText(path, value); } public setText(path: string, text: string) { this.getNode(path).getComponent(Label).text = text; } onDestroy() { this._vo.destroy() } update() { this._vo.update() } 这里主要封装了一个bindText方法。 这样,只要写this.bindText(文本节点路径,关系表达式)就可以让文本和相关的数据绑定了。 在相关的数据更改后,文本会自动刷新。无需考虑在哪些时间点抛事件来时节点刷新。 #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)