QFramework v1.0 使用指南 架构篇 07. 使用 BindableProperty 优化事件-辣魅当家漫画

在这篇我们介绍一个新的概念 BindableProperty。

BindableProperty 是包含 数据 + 数据变更事件 的一个对象。

BindableProperty 基本使用

简单的用法如下:

var age = new BindableProperty<int>(10);age.Register(newAge=>{    Debug.Log(newAge)}).UnRegisterWhenGameObjectDestoryed(gameObject);age++;age--;// 输出结果// 11// 10

非常简单,就是当调用 age++ 和 age-- 的时候,就会触发数据变更事件。

BindableProperty 除了提供 Register 这个 API 之外,还提供了 RegisterWithInitValue API,意思是 注册时 先把当前值返回过来。

具体用法如下:

var age = new BindableProperty<int>(5);age.RegisterWithInitValue(newAge => {    Debug.Log(newAge);  });// 输出结果// 5

这个 API 就是,没有任何变化的情况下,age 先返回一个当前的值,比较方便用于显示初始界面。

BindableProperty 是一个独立的工具,可以脱离 QFramework 架构使用,也就是说不用非要用 QFramework 的 MVC 才能用 BindableProperty,而是可以再自己项目中随意使用。

使用 BindableProperty 优化 CounterApp 的代码

我们直接优化即可,优化后代码如下:

using UnityEngine;using UnityEngine.UI;namespace QFramework.Example{        // 1. 定义一个 Model 对象    public class CounterAppModel : AbstractModel    {        public BindableProperty<int> Count { get; } = new BindableProperty<int>();        protected override void OnInit()        {            var storage = this.GetUtility<Storage>();                        // 设置初始值(不触发事件)            Count.SetValueWithoutEvent(storage.LoadInt(nameof(Count)));            // 当数据变更时 存储数据            Count.Register(newCount =>            {                storage.SaveInt(nameof(Count),newCount);            });        }    }    public class AchievementSystem : AbstractSystem     {        protected override void OnInit()        {            this.GetModel<CounterAppModel>() // -+                .Count                .Register(newCount =>                {                    if (newCount == 10)                    {                        Debug.Log("触发 点击达人 成就");                    }                    else if (newCount == 20)                    {                        Debug.Log("触发 点击专家 成就");                    }                    else if (newCount == -10)                    {                        Debug.Log("触发 点击菜鸟 成就");                    }                });        }    }    // 定义 utility 层    public class Storage : IUtility    {        public void SaveInt(string key, int value)        {            PlayerPrefs.SetInt(key,value);        }        public int LoadInt(string key, int defaultValue = 0)        {            return PlayerPrefs.GetInt(key, defaultValue);        }    }    // 2.定义一个架构(提供 MVC、分层、模块管理等)    public class CounterApp : Architecture<CounterApp>    {        protected override void Init()        {            // 注册 System             this.RegisterSystem(new AchievementSystem()); // +                         // 注册 Model            this.RegisterModel(new CounterAppModel());                        // 注册存储工具的对象            this.RegisterUtility(new Storage());        }    }    // 引入 Command    public class IncreaseCountCommand : AbstractCommand     {        protected override void OnExecute()        {            var model = this.GetModel<CounterAppModel>();                            model.Count.Value++; // -+        }    }        public class DecreaseCountCommand : AbstractCommand    {        protected override void OnExecute()        {            this.GetModel<CounterAppModel>().Count.Value--; // -+        }    }    // Controller    public class CounterAppController : MonoBehaviour , IController /* 3.实现 IController 接口 */    {        // View        private Button mBtnAdd;        private Button mBtnSub;        private Text mCountText;                // 4. Model        private CounterAppModel mModel;        void Start()        {            // 5. 获取模型            mModel = this.GetModel<CounterAppModel>();                        // View 组件获取            mBtnAdd = transform.Find("BtnAdd").GetComponent<Button>();            mBtnSub = transform.Find("BtnSub").GetComponent<Button>();            mCountText = transform.Find("CountText").GetComponent<Text>();                                    // 监听输入            mBtnAdd.onClick.AddListener(() =>            {                // 交互逻辑                this.SendCommand<IncreaseCountCommand>();            });                        mBtnSub.onClick.AddListener(() =>            {                // 交互逻辑                this.SendCommand(new DecreaseCountCommand(/* 这里可以传参(如果有) */));            });            // 表现逻辑            mModel.Count.RegisterWithInitValue(newCount => // -+            {                UpdateView();            }).UnRegisterWhenGameObjectDestroyed(gameObject);        }                void UpdateView()        {            mCountText.text = mModel.Count.ToString();        }        // 3.        public IArchitecture GetArchitecture()        {            return CounterApp.Interface;        }        private void OnDestroy()        {            // 8. 将 Model 设置为空            mModel = null;        }    }}

代码改动很多,重要的改动为:

Model 中的 Count 和 mCount 改成了一个叫做 Count 的 BindableProperty

删掉了 CountChangeEvent 改用监听 BindableProperty

Controller 在初始化中去掉一次 UpdateView 的主动调用

可以说代码量一下子少了很多。

我们看下运行结果:

运行没问题。

由于我们的 Count 数据,是单个数据 + 事件变更的形式,所以用 BindableProperty 非常合适,可以少写很多代码。

一般情况下,像主角的金币、分数等数据非常适合用 BindableProperty 的方式实现。

好了 BindableProperty 我们就介绍到这里。

更多内容

转载请注明地址:liangxiegame.com (首发) 微信公众号:凉鞋的笔记

QFramework 主页:qframework.cn

QFramework 交流群: 623597263

QFramework Github 地址: https://github.com/liangxiegame/qframework

QFramework Gitee 地址:https://gitee.com/liangxiegame/QFramework

GamePix 独立游戏学院 & Unity 进阶小班地址:https://www.gamepixedu.com/

【星之迟迟】 定制 NO.016 黑制服 [68P3V 534MB]
2021-02-14
【九曲Jean】 海边獒犬 [9P 85MB]
2021-03-03
目前,根据同名漫画改编的TV动画《五等分的花嫁》,正在与“ぱるてのんプロ”展开联动,于4月26日至5月12日期间开设联动咖啡厅。在联动咖啡厅中,除了可以品尝带有原作世界观的菜品,还可以获得限定原创徽章和杯垫等特典。
2022-10-28
由古馆春一原作的漫画《排球少年!!》决定制作动画剧场版的续篇《排球少年!!FINAL》,并接近了动画和相关活动,将于2023年8月上映!
2022-10-28
《无职转生》TV 动画官网近日宣布,动画第二季首播日期为 7 月 2 日。官方还公布了新的正式 PV 和新主视觉图。动画正式PV:第二季将从主角鲁迪乌斯的长大后的学院篇。第一季的助理监督平野宏树这一季将被更换为总监督,系列构成为大野敏哉。作为专门为该动画成立的公司,Studio Bind 自然保持大多数原班人马制作第二季。
2023-05-29
Epic是个和Steam类似的游戏平 台,Epic本来只是《堡垒之夜》的启动器,现逐渐转变为EPIC Games旗下的衍生游戏平 台。目前旗下已经有了各种类型游戏,例如《底特律:成为人类》、《无主之地3》。不过很多玩家在启动Epic时都遇到了一直转圈进不去的问题进不去去一般都是网络的问题,前面说的和Steam类似,也就是说Epic有时候不优(加)化(速)的话是进不去的,直连能进去的话,领游戏又报错,遇到这个问题不用慌张,打开暴喵加速器,直接搜索Epic,直接点击加速加速后重新启动一下我们的Epic,即可正
2022-09-30
[pixiv] 插画今日排行榜 2023年5月28日
2023-05-29
【Amanda Welp】 Poison [18P 39MB]
2023-06-02
雯妹 魅魔本 the countess of devil
2021-05-03
【Hatori Sama】 10th Villager [10P 130MB]
2023-06-02