PrefaceTwo-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:
Publish-Subscriber PatternThe 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 CallHTML 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)) } SummarizeThis 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:
|
<<: 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
Comprehensive understanding of html.css overflow ...
Typically, we use the following SQL statement to ...
When using docker images, images with both REPOSI...
css3 background image related Compatibility: IE9+...
Table of contents explain: Summarize Replenish Un...
Copy code The code is as follows: <style> ....
1. The ENV instruction in the Dockerfile is used ...
Background of the problem The server monitoring s...
I want to make a page using CSS3 rounded corners ...
Table of contents 1. Globally registered componen...
Table of contents 1. Scenario 2. Simplify the und...
Table of contents Docker-Maven-Plugin Maven plugi...
Preface ActiveMQ is the most popular and powerful...
Table of contents 1 Introduction 2 Trigger Introd...