Simple implementation method of two-way data binding in js project

Simple implementation method of two-way data binding in js project

Preface

Two-way data binding means that when the properties of an object change, the corresponding UI can be changed at the same time, and vice versa. In other words, if we have a user object that has a name property, whenever you set a new value for user.name, the UI will also display the new value. Likewise, if the UI includes an input box for a data user's name, entering a new value will cause the name property of the user object to be updated accordingly.

Many popular JavaScript frameworks like Ember.js, Angular.js or KnockoutJS promote two-way data binding as one of their main features. This doesn’t mean it’s hard to implement it from scratch, nor does it mean that using these frameworks is our only option when we need this kind of functionality. The underlying idea is actually quite basic, and implementing it can be boiled down to the following three points:

  • We need a way to determine which UI element is bound to which property.
  • We need to monitor changes in properties and UI
  • We need to propagate changes to all bound objects and UI elements.

Publish-Subscriber Pattern

The publish-subscribe model is actually a one-to-many dependency relationship between objects. When the state of an object changes, all objects that depend on it will be notified of the state change.

The subscriber registers (Subscribe) the event he wants to subscribe to to the dispatch center (Event Channel). When the publisher (Publisher) publishes the event (Publish Event) to the dispatch center, that is, when the event is triggered, the dispatch center uniformly dispatches (Fire Event) the processing code registered by the subscriber to the dispatch center.

result

Call

HTML call end binding data-bind-phone="name"

  <ul>

       <li class="block-phone fix bd-bottom">

            <label for="J_verificationPhone" data-bind-phone="tishi"><span>Phone number</span></label>

            <input class="fix1" id="J_verificationPhone" data-bind-phone="name" name="phone" type="text" />

            <button class="right J_clickTime" type="button">

            <span class="award-messages-btn2 J_messagesBtn1">Get verification code</span>

            <span class="award-messages-btn2 J_messagesBtn2 none"><i>Resend after 60</i> seconds</span>

          </button>

     </li>

       <li class="block-verification fix">

            <label for="J_verificationCode"><span>Verification Code</span></label>

            <input class="fix1" data-bind-code="tishi" id="J_verificationCode" data-bind-phone="name" name="verification-code" class="" type="" />

       </li>

   </ul>

js call see the following code comments

/**
 * function verificationCallback callback method* [$btn1 description]
 * data-bind-phone="name"
 * @message {[type]} The changed field phone
 * @prop_name {[type]} value name of the field
 * @target {[type]} target jsdom object;
 * @targetValue {[type]} value of the target jsdom object
 */// Listen to the callback function, the function will get the value of targetvalue, target js dom object, which is convenient for operating the changed fields! ! !
var User = require('../../entry/module/twoWayAudio.js');
var phone = new User('phone',verificationCallback);
 function verificationCallback(message,prop_name,target,targetValue){
}

Imported source code twoWayAudio

function DataBinder(object_id,verificationCallback){
  // Create a simple pubSub object var pubSub = {
callbacks: {},
on: function(msg,callback) {
this.callbacks[msg] = this.callbacks[msg] || [];
this.callbacks[msg].push(callback);
},
publish: function(msg) {
\

this.callbacks[msg] = this.callbacks[msg] || [];
for (var i = 0, len = this.callbacks[msg].length; i < len; i++) {
this.callbacks[msg][i].apply(this,arguments);
};
}
},

data_attr = "data-bind-" + object_id,
message = object_id + ":change",
changeHandler = function(event) {
var target = event.target || event.srcElement, // IE8 compatible prop_name = target.getAttribute(data_attr);
if (prop_name && prop_name !== "") {
if (verificationCallback) {
var targetValue = target.value;
verificationCallback (message,prop_name,target,targetValue);
}
pubSub.publish(message,prop_name,target.value);
}
};

// Listen for event changes and proxy to pubSub
if (document.addEventListener) {
document.addEventListener("keyup",changeHandler,false);
} else{
// IE8 uses attachEvent instead of addEventListener
document.attachEvent("onkeyup",changeHandler);
};

// pubSub propagates changes to all bound elements pubSub.on(message,function(event,prop_name,new_val){
var elements = document.querySelectorAll("[" + data_attr + "=" +prop_name + "]"),
tag_name;
for (var i = 0, len = elements.length; i < len; i++) {
tag_name = elements[i].tagName.toLowerCase();
if (tag_name === "input" || tag_name === "textarea" || tag_name === "select") {
elements[i].value = new_val;

} else{
elements[i].innerHTML = new_val;
};
};
})
return pubSub;
}

function User(uid,verificationCallback) {
  var binder = new DataBinder(uid,verificationCallback),
  user = {
  attribute : {},
  // The attribute setter uses the data binder pubSub to publish set : function (attr_name, val) {
  this.attribute[attr_name] = val;
  binder.publish(uid + ":change",attr_name,val,this);
  },
  get : function (attr_name) {
  return this.attribute[attr_name];
  },
  _binder : binder
  };

binder.on(uid + ":change",function(event,attr_name,new_val,initiator) {
if (initiator !== user) {
user.set(attr_name,new_val);
}
});
return user;
}
module.exports = User;
// phone.set( "name", "lwl" );
  // phone.set( "tishi", "提示" );

Alternative solutions

The above is just a cover for two-way data binding. In fact, this requirement can be implemented more simply.

 $('.block-phone #phone')[0].oninput=function(){
 console.log($(this))
}

Summarize

This concludes this article on the simple implementation method of two-way data binding in js projects. For more relevant js two-way data binding implementation content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue.js data binding methods (one-way, two-way and one-time binding)
  • Implement very simple js two-way data binding
  • Summary of three ways to implement two-way data binding in javascript
  • Easily implement two-way binding of javascript data
  • Detailed explanation of two-way data binding in JavaScript
  • JS native data two-way binding implementation code
  • JS data two-way binding principle and usage example analysis
  • Analysis of the method of realizing two-way binding of view and data in js

<<:  The most convenient way to build a Zookeeper server in history (recommended)

>>:  Detailed explanation of mysql MGR single-master and multi-master mode switching knowledge points

Recommend

Comprehensive understanding of html.css overflow

Comprehensive understanding of html.css overflow ...

Several ways to update batches in MySQL

Typically, we use the following SQL statement to ...

Docker renames the image name and TAG operation

When using docker images, images with both REPOSI...

A brief discussion on the principle of Vue's two-way event binding v-model

Table of contents explain: Summarize Replenish Un...

Detailed explanation of the specific use of the ENV instruction in Dockerfile

1. The ENV instruction in the Dockerfile is used ...

Let IE6, IE7, IE8 support CSS3 rounded corners and shadow styles

I want to make a page using CSS3 rounded corners ...

Introduction to install method in Vue

Table of contents 1. Globally registered componen...

Quickjs encapsulates JavaScript sandbox details

Table of contents 1. Scenario 2. Simplify the und...

Detailed usage of docker-maven-plugin

Table of contents Docker-Maven-Plugin Maven plugi...

Docker learning method steps to build ActiveMQ message service

Preface ActiveMQ is the most popular and powerful...

Detailed explanation of MySQL database triggers

Table of contents 1 Introduction 2 Trigger Introd...