Three methods to implement bidirectional data binding in javascript

Source: Internet
Author: User
This article mainly introduces three methods to achieve two-way Data Binding in javascript. The front-end view layer and data layer sometimes require two-way binding. Currently, there are three main methods to achieve two-way data binding, for more information, see. This article mainly introduces three methods to achieve two-way Data Binding in javascript. The front-end view layer and data layer sometimes require two-way binding. Currently, there are three main methods to achieve two-way data binding, for more information, see.

Two-way binding of front-end data

The front-end view layer and data layer sometimes require bidirectional binding, such as mvvm framework, data-driven view, and view state machine, I have studied several mainstream two-way data binding frameworks and summarized them. Currently, two-way data binding is implemented in the following three types.

1. Manually bind

The old implementation method is somewhat like the observer programming mode. The main idea is to define the get and set methods on the Data Object (of course there are other methods ), when calling the get or set data manually, the rendering operation on the UI Layer is started after the data is changed. In scenarios where views drive data changes, the main applications and elements such as input, select, and textarea are used, when the UI Layer changes, you can listen to dom changes, keypress, keyup, and other events to change the data at the data layer. The entire process is completed through function calls.

  
   Data-binding-method-set    

Script var elems = [document. getElementById ('El'), document. getElementById ('input')]; var data = {value: 'Hello! '}; Var command = {text: function (str) {this. innerHTML = str ;}, value: function (str) {this. setAttribute ('value', str) ;}}; var scan = function () {/*** scan node attributes with instructions */for (var I = 0, len = elems. length; I <len; I ++) {var elem = elems [I]; elem. command = []; for (var j = 0, len1 = elem. attributes. length; j <len1; j ++) {var attr = elem. attributes [j]; if (attr. nodeName. indexOf ('q-')> = 0) {/*** call the attribute command. Here you can use data change detection */command [attr. nodeName. slice (2)]. call (elem, data [attr. nodeValue]); elem. command. push (attr. nodeName. slice (2) ;}}}/*** scan data after setting */function mvSet (key, value) {data [key] = value; scan ();} /*** Data Binding listener */elems [1]. addEventListener ('keyup', function (e) {mvSet ('value', e.tar get. value) ;}, false); scan ();/*** change data update view */setTimeout (function () {mvSet ('value ', 'fuck') ;}, 1000) script

2. Dirty checking mechanism

Angularjs, a typical mvvm framework, is used to update operations on the UI Layer by checking dirty data. For more information about angular dirty detection, see-the dirty detection mechanism does not use timed detection. -The dirty data is detected when the data changes. -Angular encapsulates common dom events and xhr events to trigger the digest process of angular. -In the digest process, all watcher instances are retrieved from the rootscope. (For details about angular design, refer to other documents. Here we only discuss data binding.) let's take a look at how to perform dirty Detection: it is mainly to find all the elements related to the data through the set data, and then compare the data changes. If the data changes, perform the command operation.

  
   Data-binding-drity-check    

Script var elems = [document. getElementById ('El'), document. getElementById ('input')]; var data = {value: 'Hello! '}; Var command = {text: function (str) {this. innerHTML = str ;}, value: function (str) {this. setAttribute ('value', str) ;}}; var scan = function (elems) {/*** scan node attributes with instructions */for (var I = 0, len = elems. length; I <len; I ++) {var elem = elems [I]; elem. command = {}; for (var j = 0, len1 = elem. attributes. length; j <len1; j ++) {var attr = elem. attributes [j]; if (attr. nodeName. indexOf ('q-event ')> = 0) {/*** call attribute command */var dataKey = elem. getAttribute ('ng-bind') | undefined;/*** initialize data */command [attr. nodeValue]. call (elem, data [dataKey]); elem. command [attr. nodeValue] = data [dataKey] ;}}} /*** dirty loop detection ** @ param {[type]} elems [description] * @ return {[type]} [description] */var digest = function (elems) {/*** scan node attributes with commands */for (var I = 0, len = elems. length; I <len; I ++) {var ele M = elems [I]; for (var j = 0, len1 = elem. attributes. length; j <len1; j ++) {var attr = elem. attributes [j]; if (attr. nodeName. indexOf ('q-event')> = 0) {/*** call attribute command */var dataKey = elem. getAttribute ('ng-bind') | undefined;/*** detects dirty data. if the data changes, run the command again. Otherwise, skip */if (elem. command [attr. nodeValue]! = Data [dataKey]) {command [attr. nodeValue]. call (elem, data [dataKey]); elem. command [attr. nodeValue] = data [dataKey] ;}}}/ *** initialize data */scan (elems ); /*** can be understood as a data hijacking listener */function $ digest (value) {var list = document. querySelectorAll ('[ng-bind =' + value + ']'); digest (list);}/*** input box data binding listener */if (document. addEventListener) {elems [1]. addEventListener ('keyup', function (e) {data. value = e.tar get. value; includigest(e.tar get. getAttribute ('ng-bind') ;}, false) ;}else {elems [1]. attachEvent ('onkeyup', function (e) {data. value = e.tar get. value; includigest(e.tar get. getAttribute ('ng-bind') ;}, false) ;}settimeout (function () {data. value = 'fuck '; /*** what to ask here? To execute $ digest, the key here is to manually call the $ digest Method to start the dirty detection */$ digest ('value');}, 2000) script

3. Hijacking)

The third method is the data hijacking method used by frameworks such as aveon. The basic idea is to use Object. defineProperty listens to the get and set attributes of Data Objects. When there is data read and value assignment, it calls the node command so that the most common = equal sign value can be used. The specific implementation is as follows:

  
   Data-binding-hijacking    

Script var elems = [document. getElementById ('El'), document. getElementById ('input')]; var data = {value: 'Hello! '}; Var command = {text: function (str) {this. innerHTML = str ;}, value: function (str) {this. setAttribute ('value', str) ;}}; var scan = function () {/*** scan node attributes with instructions */for (var I = 0, len = elems. length; I <len; I ++) {var elem = elems [I]; elem. command = []; for (var j = 0, len1 = elem. attributes. length; j <len1; j ++) {var attr = elem. attributes [j]; if (attr. nodeName. indexOf ('q-')> = 0) {/*** call attribute command */command [attr. nodeName. slice (2)]. call (elem, data [attr. nodeValue]); elem. command. push (attr. nodeName. slice (2) ;}}} var bValue;/*** defines attribute settings to hijack */var defineGetAndSet = function (obj, propName) {try {Object. defineProperty (obj, propName, {get: function () {return bValue ;}, set: function (newValue) {bValue = newValue; scan () ;}, enumerable: true, retriable: true});} catch (error) {console. log ("browser not supported. ") ;}}/***** initialize data */scan ();/***** can be understood as a data hijacking listener */defineGetAndSet (data, 'value '); /*** Data Binding listener */if (document. addEventListener) {elems [1]. addEventListener ('keyup', function (e) {data. value = e.tar get. value ;}, false) ;}else {elems [1]. attachEvent ('onkeyup', function (e) {data. value = e.tar get. value ;}, false) ;}settimeout (function () {data. value = 'fuck';}, 2000) script

But it is worth noting that defineProperty supports IE8 and later browsers. here we can use defineGetter and defineSetter for compatibility, but the reason for browser compatibility is that we can simply use defineProperty. Internet Explorer 8 still needs to use other methods for hack. Run the following code to hack IE8 and defineProperty supports IE8. For example, you can use es5-shim.js. (Ignore in IE 8 or earlier browsers)

4. Summary

First, the example here is just a simple implementation. Readers can deeply understand the similarities and differences between the three methods. A complicated framework also uses this basic idea to snowball roll.

The above is the details about the three methods to achieve two-way Data Binding in javascript. For more information, see other related articles in the first PHP community!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.