前言

简单介绍一下双向数据绑定实现的是一个什么样的东西。首先有两个东西,他们分别是:

V-视图层

M-数据层

1、视图层传向数据层:V发生改变,M也发生改变

2、数据层传向视图层:M发生改变,V也发生改变

那么接下来我们也将自己书写代码实现这样两种功能,从而实现双向数据绑定。最终实现的效果如图:

修改input框里面的内容,p标签内容也实时相对应发生改变,data里面的数据也会发生改变

一、先奉献上自己完整的代码

这里我是基于jQuery进行的代码编写,其中的方法将在下面进行详细的解析

;(function($,doc,win) {var VM = function(opt) { this.setting = {}; $.extend(this.setting, opt.data); // 初始化VM this.init();};VM.prototype = { init: function() { this.render('input'); this._render('p'); }, render: function(dom) { var self = this , data = self.setting; $(dom).each(function() { var _attr = $(this).attr('xq-model'); if (_attr !== undefined) { if (data[_attr] !== undefined) { $(this).attr('value', data[_attr]); self.inputChange($(this), _attr); } } }); }, _render: function(dom) { var self = this; $(dom).each(function() { var val = $(this).html() || $(this).text() || $(this).val(); if (val.indexOf('}}') !== -1 && val.indexOf('}}') !== -1) { val = val.replace(/^s+|{{|s+/,''); val = val.replace(/}}|[s+]/g,''); self.labelChange(this, val); } }) }, labelRender: function(dom, _attr) { var self = this , data = self.setting; $(dom).each(function() { var val = $(this).attr(_attr); if (val !== undefined) { if (data[_attr] !== undefined) { $(this).html(data[_attr]) || $(this).text(data[_attr]) || $(this).val(data[_attr]); } } }) }, inputChange: function(_this, _attr) { var self = this , data = self.setting; _this.unbind('keydown'); _this.keydown(function(){ _this.unbind('keyup'); _this.keyup(function() { var changeVal = _this.val() , oldVal = data[_attr]; data[_attr] = changeVal; self.render('input'); self.labelRender('p', _attr); }) }) }, labelChange: function(_this,val) { var self = this , data = self.setting; if (val !== undefined) { if (data[val] !== undefined) { $(_this).html(data[val]) || $(_this).text(data[val]) || $(_this).val(data[val]); } } $(_this).attr(val,'') }};window.VM = VM;})(jQuery,document,window);

二、创建自己的绑定规则

这里关于指令,我没有做作用域的包裹,比较完善的是需要用一个controller指令讲需要展示的view视图层包裹起来的。如果有想法的小伙伴们可以在最后自行去思考,接下来先直接上html代码

双向数据绑定

{{ msg }}

{{ my }}

这里我制定的双向指令是xq-model,内容的解析规则是{{}}。大家有自己喜欢的指令可以自行制定。

三、实现自己的绑定规则

我们现在需要做的就是一步一步去实现我们自己规定的一些绑定规则

首先我们需要做的第一步就是渲染出input中的xq-model指令指定的数据

/** * [render input框渲染] * @param {[type]} dom [input] */render: function(dom) { var self = this , data = self.setting; // 遍历dom中所有的input,搜寻带xq-model指令的input $(dom).each(function() { var _attr = $(this).attr('xq-model'); // 判断是否有对应绑定data数据 if (_attr !== undefined) { if (data[_attr] !== undefined) { $(this).attr('value', data[_attr]); // 调用input值改变方法 self.inputChange($(this), _attr); } } });}

实现inputChange方法

/** * [inputChange 值改变] * @param {[type]} _this [当前input] * @param {[type]} _attr [当前绑定对应的data数据] */inputChange: function(_this, _attr) { var self = this , data = self.setting; // 绑定键盘事件进行监听 _this.unbind('keydown'); _this.keydown(function(){ _this.unbind('keyup'); _this.keyup(function() { var changeVal = _this.val() , oldVal = data[_attr]; data[_attr] = changeVal; // 调用input框渲染方法 self.render('input'); // 调用标签值改变渲染方法 self.labelRender('p', _attr); }) })}

到这里,对于input框的渲染及data数据的双向算完成了第一个了,接下来我们需要实现的便是对于标签的渲染

/** * [_render 标签渲染] * @param {[type]} dom [element] */_render: function(dom) { var self = this; // 遍历标签,拿到里面的内容 $(dom).each(function() { var val = $(this).html() || $(this).text() || $(this).val(); // 判断是否存在{{}},并截取拿到{{}} 里面的内容 if (val.indexOf('}}') !== -1 && val.indexOf('}}') !== -1) { val = val.replace(/^s+|{{|s+/,''); val = val.replace(/}}|[s+]/g,''); // 调用标签赋值方法 self.labelChange(this, val); } })}

实现labelChange方法

/** * [inputChange 值改变] * @param {[type]} _this [当前input] * @param {[type]} _attr [当前绑定对应的data数据] */labelChange: function(_this,val) { var self = this , data = self.setting; if (val !== undefined) { if (data[val] !== undefined) { $(_this).html(data[val]) || $(_this).text(data[val]) || $(_this).val(data[val]); } } // 给当前对象绑定一个属性对应其data数据 $(_this).attr(val,'')}

最后实现input框输入,实时修改对应的标签的值labelRender方法

/** * [labelRender 标签实时渲染] * @param {[type]} dom [element] * @param {[type]} _attr [当前data数据的key] */labelRender: function(dom, _attr) { var self = this , data = self.setting; $(dom).each(function() { // 通过labelChange获取到对应data数据的attr属性 var val = $(this).attr(_attr); if (val !== undefined) { if (data[_attr] !== undefined) { $(this).html(data[_attr]) || $(this).text(data[_attr]) || $(this).val(data[_attr]); } } })}

最后我们调用一下实现好的VM

$(function() { new VM({ data: { msg: 'hello', my: 'hehe' } });})

好了,属于我们自己的一个简单的双向数据绑定至此便算是完成了,大家也可以自己将这个进行不断的完善,自己去实现一个完整的双向数据绑定。小伙伴们,加油↖(^ω^)↗

原文发布时间为:2021年05月22日2021年05月22日原文作者:qiangdada

本文来源:开源中国 如需转载请联系原作者

c语言一次绑定多个控件,一入前端深似海,从此红尘是路人系列第九弹之如何实现一个双向数据绑定...相关推荐

  1. asp.net中将数据库绑定到DataList控件的实现方法与实例代码

    解决方法1: datalist databind() 解决方法2: 查看MSDN上的详细说明资料 解决方法3: 在DataList的模板中用table表格,如: 复制代码 代码如下: <asp: ...

  2. 动态生成表格呈现还是将表格直接绑定gridview等控件呈现的开发方式选择依据...

    动态生成表格呈现还是将表格直接绑定gridview等控件呈现的开发方式选择依据:由存储过程决定,如果编写的存储过程可以生成需要呈现的表格则直接绑定,否则要动态生成表格 转载于:https://www. ...

  3. WPF 绑定StaticResource到控件的方法

    WPF 绑定StaticResource到控件的方法 原文:WPF 绑定StaticResource到控件的方法 资源文件内的属性能否直接通过绑定应用到控件?答案是肯定的. 比如,我们要直接把下面的& ...

  4. GroupBox控件拖入FlowLayoutPanel控件之后消失

    GroupBox控件拖入FlowLayoutPanel控件之后消失 在C#Winform当中添加控件 GroupBox控件拖入FlowLayoutPanel控件之后消失不见,其实是GroupBox控件 ...

  5. java实现控件绑定数据源_控件(三)——TreeView控件以XmlDataSource控件为数据源实现简单的绑定...

    TreeView控件功能非常强大,今天,我们只是窥其一角. 我们实现的例子是:TreeView控件与XmlDataSource控件绑定,然后在网页显示选中项. 首先我们添加一个xml,取名为tv.xm ...

  6. Android视图绑定,设置控件点击事件不生效

    我遇到的问题是: setContentView(R.layout.acitivty_main); setContentView(mainBinding.getRoot); 应该使用下面的来绑定布局,不 ...

  7. 中年人学C语言Windows程序设计,30 DialogBox控件

    DialogBox控件 1.DialogBox 函数功能:该宏根据对话框模板资源创建一个模态的对话框.DialogBOX函数直到指定的回调函数通过调用EndDialog函数中止模态的对话框才能返回控制 ...

  8. c语言 操作ie文本框,IE控件一些高级使用方法

    // 显示一个空白网页 m_ie.Navigate2( &CComVariant(_T("about:blank")),NULL,NULL,NULL,NULL); // 得 ...

  9. VS2010环境下MFC使用DataGrid绑定数据源以及控件注册问题解决

    http://www.cnblogs.com/panweishadow/archive/2013/07/25/3214629.html 参考:http://blog.csdn.net/fddqfddq ...

最新文章

  1. 【BIEE】数据透视表格第一列添加序号
  2. Python的零基础超详细讲解(第六天)-Python的数字类
  3. 两个例子详解并发编程的可见性问题和有序性问题,通过volatile保证可见性和有序性以及volatile的底层原理——缓存一致性协议MESI和内存屏障禁止指令重排
  4. java成员方法的一般格式为_Java基本知识(四)
  5. HBase之Region上Spilt流程分析
  6. 被调用的对象已与其客户端断开连接 win10_【完整案例】基于Socket开发TCP传输客户端...
  7. 操作系统学习笔记 002 安装NASM
  8. linux less命令详解
  9. Stata | 初试
  10. 常见的Wi-Fi协议------802a/b/g/n/ac系列
  11. 电脑测试耗电量软件,有测验电脑耗电量的软件么 ?
  12. 大一新生HTML期末作业 学生个人网页设计作业 HTML5响应式个人简历网站模板 web前端网页制作课作业
  13. java知识点ppt背景图片_Java 给 PowerPoint 文档添加背景颜色和背景图片
  14. 【字符串处理函数】sprintf与snprintf
  15. Dell服务器组建阵列-Raid(无阵列卡)
  16. Linux学习笔记 Day0
  17. 交易中的 “道“ 与 “术“
  18. 开始闭关修炼 冥思微软之大未来
  19. [转贴]“汉龙小学”无一死亡奇迹背后的真相
  20. css用flex实现字体垂直居中对齐

热门文章

  1. NameError: name 'random' is not defined
  2. ios10前台收到推送_IOS - 前台时的推送弹窗效果
  3. 继微博之后,抖音、今日头条、小红书宣布将显示账号IP属地
  4. 20分钟充满!华为P50系列或最高支持100W超级快充
  5. 网易丁磊:给我100个亿,也不会躺平
  6. 腾讯社交电商小鹅拼拼 如何突围万亿社交电商赛道?
  7. 雷军变身IPO收割机:坐拥4家上市公司,今年至少收获8个IPO!
  8. 蚂蚁集团上市 员工身价暴涨人均一套房?支付宝:没有 但会努力的
  9. 台积电对世界最大创新贡献是什么?总裁魏哲家这样说...
  10. 董明珠:雷军的产品基本是贴牌生产,若自己建厂,他肯定做不过我