扣丁学堂HTML5培训简述实现数据双向绑定的方式

实现数据双向绑定的方式有多少小伙伴知道呢?不知道的小伙伴也没有关系,本篇文章扣丁学堂HTML5培训小编就给读者们分享一下,希望对小伙伴们有所帮助。

扣丁学堂HTML5培训简述实现数据双向绑定的方式

扣丁学堂HTML5培训

双向数据绑定底层的思想非常的基本,它可以被压缩成为三个步骤:

我们需要一个方法来识别哪个UI元素被绑定了相应的属性(上面的例子里直接选中了元素,而没有提供对外的函数)

我们需要监视属性和UI元素的变化

我们需要将所有变化传播到绑定的对象和元素

常见的实现数据绑定的方法,有大致如下几种:

发布者-订阅者模式

脏值检查

数据劫持

其中最简单也是最有效的途径,是使用发布者-订阅者模式。上面的例子就使用到了。

发布者-订阅者模式的思想很简单:使用自定义的data属性在HTML代码中指明绑定。所有绑定起来的JavaScript对象以及DOM元素都将“订阅”一个发布者对象。任何时候,如果某一个被绑定的内容(如JavaScript对象或者一个HTML输入字段)被侦测到发生了变化,我们将代理事件到发布者-订阅者模式,这会反过来将变化广播并传播到所有绑定的对象和元素。下面是一个来自谈谈JavaScript中的双向数据绑定的例子,我在注释里添加了一些我的理解。

function DataBinder(object_id){

//创建一个简单地PubSub对象

var pubSub = { // 一个pubSub 对象,内部有一个 callbacks 对象,保存回调函数

callbacks: {}, // 键名为触发回调函数的自定义事件名称,值为一个数组,每一项都是一个回调函数

on: function(msg,callback){ // on 方法 传入参数,一个字符串(就是自定义事件的名称),一个回调函数

this.callbacks[msg] = this.callbacks[msg] || []; // 以 msg 作为键名,创建数组(如果存在,等于原数组)

this.callbacks[msg].push(callback); // 将新的回调函数加入数组

},

publish: function(msg){ // publish 方法

this.callbacks[msg] = this.callbacks[msg] || []; // 根据 msg 传入的参数,调用 this.callbacks 对象 的 msg 属性保存的数组,如果没有,等于新建的空数组

for(var i = 0, len = this.callbacks[msg].length; i<len;i++){ // 循环调用所有注册在了 msg 里的回调函数

this.callbacks[msg][i].apply(this,arguments); // 调用注册的回调函数时,将 this 指向 publish 的调用者, 参数为 publish 函数调用时传入的参数

}

}

},

data_attr = "data-bind-" + object_id, // 产生一个字符串,对传入的参数进行处理,加上“data-bind”前缀加上,后面会用这个字符串作为属性名,获得需要绑定的元素

message = object_id + ":change", // 产生一个字符串,对传入的参数进行处理,加上“:change”后缀加上,后面会用这个字符串作为事件名,将事件派发给接收的元素

changeHandler = function(evt){ // 根据事件的触发者,判断是否是监听的数据

var target = evt.target || evt.srcElemnt, //IE8兼容 触发事件的元素

prop_name = target.getAttribute(data_attr); // 得到元素的 data_attr 属性

if(prop_name && prop_name !== ""){ // 根据元素属性,判断是否是监听的元素

pubSub.publish(message,prop_name,target.value); // 广播 message 事件,调用所以注册了 message 事件的函数,调用注册的回调函数时,将 this 指向 publish 的调用者, 参数为 publish 函数调用时传入的参数(publish 函数内部有 apply)

}

};

//监听变化事件并代理到PubSub

if(document.addEventListener){ // 监听整个文档的变化,并调用 changeHandler 函数

document.addEventListener("change",changeHandler,false);

}else{

//IE8使用attachEvent而不是addEventListener

document.attachEvent("onchange",changeHandler);

}

//PubSub将变化传播到所有绑定元素

pubSub.on(message,function(vet,prop_name,new_val){ // 调用 pubSub.on 方法,注册 message 事件的回调函数,本例中,message 事件也只绑定了一个回调函数,就是这个匿名函数,功能是将变化元素的值传入所有被监听的元素

var elements = document.querySelectorAll("[" + data_attr + "=" + prop_name + "]"), // 根据传入的参数,获得所以需要接受数据的元素

tah_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;

}

//在model的设置器中

function User(uid){

var binder = new DataBinder(uid), // 返回一个 pubSub 对象,其上保存了由传入参数 uid 确定的元素所有绑定的回调函数

user = {

attributes: {}, // 保存需要同步的数据

set: function(attr_name,val){ // 调用 set 方法,将需要同步的数据通过 publish 方法传给监听的元素

this.attributes[attr_name] = val;

//使用“publish”方法

binder.publish(uid+ ":change", attr_name, val,this);

},

get: function(attr_name){

return this.attributes[attr_name];

}

}

return user; // 函数作为一个构造函数时,返回一个对象,作为这个构造函数的实例

}

var user = new User(123); // 返回一个 user 对象,对象有一个 attributes 属性指向一个对象,这个对象保存这需要同步的数据。

user.set("name","Wolfgang"); // 所有带有 data-bind-123="name" 属性的 html 标签都会被监听,它们的值会同步改变,保持相同。

然后说脏检查,脏检查是一种不关心你如何以及何时改变的数据,只关心在特定的检查阶段数据是否改变的数据监听技术。简单来说,脏检查是直接检测数据是否改变,如果某一个被监听的数据改变,就将这个值传给所有被被监听者。

而数据劫持,就是通过对属性的 set get 方法进行改造,来监测数据的改变,发布消息给订阅者,触发相应的监听回调。

以上就是扣丁学堂HTML5在线学习小编给大家分享的实现数据双向绑定的方式,希望对小伙伴们有所帮助,想要了解更多内容的小伙伴可以登录扣丁学堂官网咨询。

想要学好HTML5开发小编给大家推荐口碑良好的扣丁学堂,扣丁学堂有专业老师制定的HTML5学习路线图辅助学员学习,此外还有与时俱进的HTML5视频教程供大家学习,想要学好HTML5开发技术的小伙伴快快行动吧。

H5进阶课程:https://ke.qq.com/course/387348?flowToken=1008605【扫码进入前端H5架构师进阶VIP体验课】

H5基础课程:https://ke.qq.com/course/320523?flowToken=1008606【扫码进入HTML5前端开发VIP免费公开课】

注:点击(了解更多)进入课程直播间

相关推荐