前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SAP UI5和Vue的双向绑定比较

SAP UI5和Vue的双向绑定比较

作者头像
Jerry Wang
发布2020-05-09 16:14:22
4670
发布2020-05-09 16:14:22
举报

Recently when I do self study on Vue I find many articles in the internet with full of praise on Vue‘s reactive Two-Way Data binding trait. This fact makes me recall my self-study on UI5 early in year 2013 and at that time, the Two-Way Data binding was already supported by UI5.

Two-way data binding in UI5

I have once already compared the Data Binding mechanism in my blog: Compare Data Binding mechanism: SAPUI5 and Angular.

Now I will reuse the button created for my blog Use Proxy pattern to make better image loading behavior in UI5 to recall UI5 two way data binding. I have a simply button defined in XML view:

代码语言:javascript
复制
<core:View xmlns:core="sap.ui.core" xmlns:common="sap.ui.commons" controllerName="buttontutorial.view.simple">
	<common:Button text="Load Image" id="jerryButton"/>
</core:View>

In controller’s onInit function, the text property is bound to field “field_for_text” in JSON model:

代码语言:javascript
复制
onInit: function(){
		var oModel = new sap.ui.model.json.JSONModel();
		var myData = {"field_for_text": "Jerry button label"};

		oModel.setData(myData);
		var button = this.getView().byId("jerryButton");
		button.setModel(oModel);
		button.bindProperty("text", "/field_for_text");
		button.oModel = oModel;
}

Two way data binding test: Control property change leads to model field change

Type the following script in Console. Before I press entry key, the field “field_for_text” is still the current label “Jerry button label” displayed in UI:

After I press enter key, the model field is changed as well.

The logic for the synchronization in this direction ( control -> model ) has already been explained in my blog: How I do self-study on a given Fiori control – part 7 UI5 binding mode.

Two way data binding test: model field change leads to control property change

Now let’s do the opposite. After I change model field and press enter key in console, nothing happens.

In order to make the change on model field flows to control property, it is necessary to call refresh function of JSON model.

The reason is: when the control property is bound to model field via this line in onInit function in my controller: utton.bindProperty(“text”, “/field_for_text”); A model change handler is registered as listener for model change event, which will be raised when refresh function is called. Inside this change handler, the control property will be updated based on the change of model field.

Two way data binding in Vue

The version of Vue I am using is 2.3.4. I am just using the hello world example provided in Vue tutorial to inspect its two way data binding trait.

代码语言:javascript
复制
<html>
<script src="lib/vue.js"></script>
<script>
function init() {
jerry = new Vue({
  el: '#app',
  data: {
    message: 'Hello World'
  }
});
}
</script>
<body onload = "init();">
<div id="app">
  <p>{{ message }}</p>
</div>
</body>
</html>

Two way data binding test: model field change leads to control property change

Change model field in console via code: jerry.$data.message = “Jerry change in Console”;

And type enter key, the UI will react accordingly:

The mechanism for this direction of synchronization is, when the Vue application is started, the compiled attribute is registered as a “reactive” field in function defineReactive:

Inside this function the native implementation of Object.defineProperty is utilized to registered a custom setter to the reactive field, which will be called whenever the change happens on that field.

When you change the value of this field in console, the old value “Hello World” is overwritten by the new value “Jerry change in Console”, and dep.notify will trigger the very control involved in this model change:

In patchVnode function, old DOM node will be replaced with new DOM node created with modified attribute done in console:

In the end the new DOM element’s attribute textContent is filled with new value of reactive field and after that we can immediately see this latest value in UI:

Two way data binding test: Control property change leads to model field change

I made some small changes on the example:

代码语言:javascript
复制
<html>
<script src="lib/vue.js"></script>
<script>
function init() {
jerry = new Vue({
  el: '#app',
  data: {
    message: 'Hello World'
  }
});
}
</script>
<body onload = "init();">
<div id="app">
  <p>{{ message }}</p>
  <input v-model="message"></input>
</div>
</body>
</html>

Now whenever I type something in input field, the model field message is changed as well. How is this achieved in Vue?

Step1 – Model directive detection

In mount phase the directive v-model is parsed, extracted and stored in the attribute directives of input element:

Step2 – Generate source code of event handler for input field based on extracted directive in previous step

It is this very line of generated code which writes back to the model field with user input:

if(event.target.composing)return;message=event.target.composing)return;message=event.target.composing)return;message=event.target.value The complete generated source code for directive “v-model=”message” could be found from below code. A real JavaScript function is created dynamically with this generated source code as function body, which will be used as the concrete event handler for the physical DOM element.

Step3 – Register event handler into physical DOM element

The registration is done using native function addEventListener.

Step4 – Model field will be changed in onInput event handler

Now as long as you type something in input field, the event handler created in step 2 and registered in step 3 will capture this event and react accordingly. Model field is changed now!

Summary

Fundamentally speaking, per above analysis, both UI5 and Vue uses the Observer pattern to implement the two way data binding. Only the slight difference is that for the notification between control and model, UI5 uses its own Observer code for bi-direction. In Vue, the notification from model to control is implemented on its own as well, whereas the opposite from control to model in the example of this blog is implemented via HTML native event.

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-05-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Two-way data binding in UI5
  • Two way data binding test: Control property change leads to model field change
  • Two way data binding test: model field change leads to control property change
  • Two way data binding in Vue
  • Two way data binding test: model field change leads to control property change
  • Two way data binding test: Control property change leads to model field change
  • Step1 – Model directive detection
  • Step2 – Generate source code of event handler for input field based on extracted directive in previous step
  • Step3 – Register event handler into physical DOM element
  • Step4 – Model field will be changed in onInput event handler
  • Summary
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档