根据GitHub代码 :GitHub - WilberTian/Two-way-data-binding: Simple examples of Two-way-data-binding in JavaScript 学习的简单操作,用"updateModelData"更新Model等操作
主动调试:
var Pubsub = { subscrib: function(ev, callback) { this._callbacks || (this._callbacks = {}); (this._callbacks[ev] || (this._callbacks[ev] = [])).push(callback); return this; }, publish: function() { var args = Array.prototype.slice.call(arguments); var ev = args.shift(); if(!this._callbacks) return this; if(!this._callbacks[ev]) return this; for(var i = 0; i < this._callbacks[ev].length; i++) { this._callbacks[ev][i].apply(this, args); } return this; } } var TBinding = (function(){ // element keyup and change callback function pageElementEventHandler(e) { var target = e.target || e.srcElemnt; var fullPropName = target.getAttribute('t-binding'); if(fullPropName && fullPropName !== '') { Pubsub.publish('ui-update-event', fullPropName, target.value); } } // add keyup and change event listener if(document.addEventListener) { document.addEventListener('keyup', pageElementEventHandler, false); document.addEventListener('change', pageElementEventHandler, false); } else { document.attachEvent('onkeyup', pageElementEventHandler); document.attachEvent('onchange', pageElementEventHandler); } // subscrib model-update-event, handle model change, then update UI Pubsub.subscrib('model-update-event', function(fullPropName, propValue) { var elements = document.querySelectorAll('[t-binding="' + fullPropName + '"]'); for(var i = 0, len =elements.length; i < len; i++){ var elementType = elements[i].tagName.toLowerCase(); if(elementType === 'input' || elementType === 'textarea' || elementType === 'select') { elements[i].value = propValue; } else { elements[i].innerHTML = propValue; } } }); return { 'modelName': '', 'initModel': function(modelName) { var self = this; self.modelName = modelName; // subscrib ui-update-event, handle ui change then update model Pubsub.subscrib('ui-update-event', function(fullPropName, propValue) { var propPathArr = fullPropName.split('.'); self.updateModelData(propPathArr[1], propValue); }); return Object.create(this); }, 'loadModelData': function(modelData) { for(prop in modelData) { this.updateModelData(prop, modelData[prop]) } }, 'updateModelData': function(propName, propValue) { eval(this.modelName)[propName] =propValue; Pubsub.publish('model-update-event', this.modelName + '.' + propName, propValue); } } })();
var user = TBinding.initModel('user'); user.loadModelData({ 'name': 'wilber', 'age': 29, 'gender': 2 }) user.incAge = function() { this.updateModelData('age', user.age + 1); } user.decAge = function() { this.updateModelData('age', user.age - 1); }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>2-way-binding</title> </head> <body> <form style="400px"> <fieldset> <legend>User info form:</legend> Name:<br> <input type='text' t-binding="user.name"></input><br/> Age:<br> <input type='text' t-binding="user.age"></input> <button type="button" onclick="user.incAge()">+</button> <button type="button" onclick="user.decAge()">-</button> <br/> Gender:<br> <select t-binding="user.gender"> <option disabled selected value></option> <option value="1">Male</option> <option value="2">Female</option> </select> </fieldset> </form> <br> <h3>User info</h3> <strong> Name: </strong> <label t-binding="user.name"></label><br> <strong> Age: </strong> <label t-binding="user.age"></label><br> <strong> Gender: </strong> <label t-binding="user.gender"></label><br> </body> <script src="tbinding.js"></script> <script src="user.js"></script> </html>