首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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

系列目录

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

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

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

(10) XML视图里的button控件

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

经过了三个多月不懈的努力,Jerry终于初步掌握了使用Angular开发企业级前端应用的技能,也通过阅读Angular源代码的方式,弄清楚了Angular的Property binding,Event bindingTwo-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,双向绑定。在调试器里,通过下图路径即可查看:

方法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的生成逻辑,敬请期待。

系列目录

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

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

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

(10) XML视图里的button控件

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

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20210110A09EAD00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券