深入学习SAP UI5框架代码系列之七:控件数据绑定的三种模式 - One Way, Two Way和OneTime实现原理比较

举报
汪子熙 发表于 2022/04/29 18:38:42 2022/04/29
【摘要】 经过了三个多月不懈的努力,Jerry终于初步掌握了使用Angular开发企业级前端应用的技能,也通过阅读Angular源代码的方式,弄清楚了Angular的Property binding,Event binding和Two-way binding的实现原理和区别。Angular这三种绑定方式的使用语法如下图所示:但咱们今天的文章不会阐述Angular的数据绑定细节,而是继续聚焦在SAP U...

经过了三个多月不懈的努力,Jerry终于初步掌握了使用Angular开发企业级前端应用的技能,也通过阅读Angular源代码的方式,弄清楚了Angular的Property binding,Event binding和Two-way binding的实现原理和区别。

Angular这三种绑定方式的使用语法如下图所示:

但咱们今天的文章不会阐述Angular的数据绑定细节,而是继续聚焦在SAP UI5上。

Jerry 前一篇文章 深入学习SAP UI5框架代码系列之六:SAP UI5控件数据绑定的实现原理,曾经展示过这张源代码截图,第83行包含了SAP UI5支持的三种数据绑定模式:

(1) OneWay:单向绑定
(2) TwoWay:双向绑定
(3) OneTime:单次绑定

从第69行代码得知,SAP UI5模型的默认绑定方式为双向绑定TwoWay.

当我第一次了解了SAP UI5三种不同的数据绑定模式时,脑子里马上浮现出一个问题:

在我们的脚手架应用里,将button控件的text属性,通过bindProperty函数,绑定到JSONModel实例的field_for_text字段上时,使用的是哪一种绑定模式?

oButton1.bindProperty("text", "/field_for_text");

答案是TwoWay,双向绑定。在调试器里,通过下图路径即可查看:

oButton1.mBindingInfos.text.binding.sMode.

方法bindProperty里创建oBinding对象时,把JSONModel的默认binding方式(sDefaultBindingMode), TwoWay, 赋给oBinding对象。

SAP UI5双向绑定的实现原理 - 数据从控件流向模型

我们调用控件的setText方法,修改控件text属性。根据SAP UI5数据双向绑定特性,控件text属性绑定到的模型字段field_for_text的值,也会自动被修改:

oButton1.setText("用js修改控件值");

从上图我们能确认,JSONModel模型实例的field_for_text也跟着被修改了。这一切是怎么发生的?

答案在Jerry之前的文章 深入学习SAP UI5框架代码系列之五:SAP UI5控件的实例数据修改和读取逻辑 介绍的button控件的setText方法里,其实已经提到过。

下图第1320行的代码,执行的逻辑正是在控件属性通过setProperty被更新的场景下,将最新值同步到对应的模型字段中去。

在updateModelProperty函数内部,有一个IF条件判断:只有当前oBinding对象实例的绑定模式为TwoWay时,才调用其setExternalValue方法,将模型字段的对应值,修改成来自控件属性通过setText更改的最新值。

这就是控件text属性的变化,能传递到对应模型字段的原理。

SAP UI5单向绑定的工作原理

通过之前的介绍我们得知,SAP UI5控件绑定的默认模式为TwoWay. 因此,我们如果要测试单向绑定,需要对已有的代码进行修改,将绑定模式显式修改成OneWay:

oButton1.bindProperty("text", "/field_for_text", undefined, "OneWay");

此时,控件text属性通过setText的修改,不会再触发JSONModel模型字段的变化,因为下图3620行IF语句的条件不再成立。这就是SAP UI5单向数据绑定的原理:数据仅仅会在模型字段到控件属性这个方向上单向流动。JSONModel字段值发生变化后,控件对应属性会自动更新。反之,控件属性通过API被修改时,不会引起JSONModel字段值的更新。

SAP UI5单次绑定的工作原理

SAP UI5官方网站上对单次绑定(OneTime)的说明:value is only read from the model once.

怎么理解这句话呢?

通过一个实际的例子来理解双向绑定和单次绑定的区别。

在双向绑定的测试代码里,添加如下两行代码:

myData["field_for_text"] = "Tom";
oModel.checkUpdate();

模型字段field_for_text的初始值,在第28行赋值为Jerry, 然后在第34行设置为Tom. 调用模型的checkUpdate方法后,控件的标签也自动刷新为Tom.

JSONModel的checkUpdate方法,会使用_fireChange,以事件通知的方式,将最新的Tom值广播出去。

that.updateProperty最后会调用SAP UI5控件的setProperty方法,把text属性的值赋成Tom.

下图展示的setProperty方法,在Jerry之前的文章 深入学习SAP UI5框架代码系列之五:SAP UI5控件的实例数据修改和读取逻辑 里有详细介绍。

现在开始测试单次绑定,将32行bindProperty函数调用里的绑定模式改成OneTime:

测试发现,在单次绑定模式下,SAP UI5控件属性和模型字段的自动同步已经中断了——button控件的text属性,保存的是调用bindProperty方法那一刻,JSONModel的field_for_text值Jerry,而不是数据绑定之后,修改成的最新值Tom.

这个行为正是SAP UI5单次绑定的正确表现。

那么为什么在单次绑定模式下,纵然我们调用了模型的checkUpdate方法,仍然无法将模型字段的最新值,通过change事件通知机制告诉给控件的监听函数呢?

答案就是,在SAP UI5控件指定了单次绑定的模式后,它"过河拆桥",马上就把响应模型change事件的监听函数拆除了(detach,取消注册之意)。

奥妙就在下图3379行代码的IF分支里:在SAP UI5控件调用bindProperty方法把控件属性绑定到模型字段时,如果当前绑定模式为OneTime,则取消控件针对模型change事件的监听函数注册。

如此一来,不论接下来模型字段的值如何变化,该变化的值通过change事件进行广播,但UI5控件再也不会收到该事件了,因而控件属性也不会再刷新。

Jerry在SAP UI5 / Angular的实际开发生涯中,一旦遇到数据绑定出问题,总能迅速找到如何排错的突破口,靠的就是对这些前端框架的数据绑定细节的熟悉。

希望本文能帮助大家对SAP UI5官方网站上解释数据绑定三种方式的说明文字,有更深入的理解,感谢阅读。

本系列下一篇文章,我们会介绍SAP UI5控件ID的生成逻辑,敬请期待。

系列目录

(0) SAP UI5应用开发人员了解UI5框架代码的意义

(1) SAP UI5 module懒加载机制

(2) SAP UI5 控件渲染机制

(3) HTML原生事件 VS SAP UI5 Semantic事件

(4) SAP UI5控件元数据的元数据实现

(5) SAP UI5控件的实例数据修改和读取逻辑

(6) SAP UI5控件数据绑定的实现原理

(7) SAP UI5控件数据绑定的三种模式:One Way, Two Way和OneTime实现原理比较(本文)

(8) SAP UI5控件ID的生成逻辑

(9) SAP UI5控件的多语言(国际化,Internationalization,i18n)支持的实现原理

(10) XML视图里的button控件

(11) button控件和它背后的DOM元素

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。