angular雙向綁定模擬探索
前言
本次探索的demo是基于jquery寫的,畢竟jquery提供了強(qiáng)大的選擇器,用慣了就離不開它了!angular的雙向綁定實(shí)在是有點(diǎn)精深,本次探索只實(shí)現(xiàn)了文本的雙向綁定。
View-Model
先看效果:文本框輸入內(nèi)容,model層數(shù)據(jù)也同步過來了
Model-View
先看效果:js改變model層數(shù)據(jù),視圖也立即隨之變化
上我的demo
<!DOCTYPE html> <html lang="en" data-swq-app = 'app'> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/jquery-1.9.1.min.js"></script> </head> <body> <input type="text" data-swq-model="name"> <input type="text" data-swq-model="age"> <div>name:<span data-swq-bind="name"></span></div> <div>age:<span data-swq-bind="age"></span></div> <script> (function(window){ //模仿angular的雙向綁定 //需要一個(gè)發(fā)布者,也就是angular里面的$scope的存在,這里我取我的大名swq,是個(gè)對(duì)象 //需要訂閱者數(shù)據(jù)容器 var swqArray = []; //訂閱者數(shù)據(jù)容器 var swqNamesArray = ['name','age']; //存放訂閱者標(biāo)識(shí)容器,這邊寫死,實(shí)際上肯定需要?jiǎng)討B(tài)獲取 window.swq ={ scanTag : function (){ var swqController = $('[data-swq-app]:first'); // view層需要和model層綁定的元素進(jìn)行事件綁定 var allModelView = swqController.find('[data-swq-model]'); allModelView.each(function(){ $(this).on('keyup',function(event){ var targetBind = $(this).data('swqModel'); var value = $(this).val(); if(targetBind && targetBind.length > 0){ swq[targetBind] = value; } }); }); // model層需要劫持綁定的進(jìn)行綁定 $.each(swqNamesArray,function(index,value){ notifyProperty(value); }) } }; //數(shù)據(jù)的變化需要反映到視圖上,因此要監(jiān)聽到數(shù)據(jù)的變化,js原生的defineProperty給我們提供了監(jiān)聽的可能,劫持更改數(shù)據(jù),思路有點(diǎn)類似前端路由的實(shí)現(xiàn)思路,我監(jiān)聽到你某個(gè)操作但是我不做你的功能,我自己定義該做的事 function notifyProperty(name){ Object.defineProperty(swq,name,{ //劫持到set方法 set : function(newValue){ swqArray[name] = newValue; // 實(shí)現(xiàn)model-view的同步 var $target = $('[data-swq-bind = "'+name+'"],[data-swq-model = "'+name+'"]'); if($target){ $target.each(function(){ var tagName = $(this)[0].tagName.toLowerCase(); if(tagName == 'input' || tagName =='select' || tagName =='textarea'){ $(this).val(newValue) }else{ $(this).text(newValue) } }) } }, //劫持到get方法,因?yàn)間et方法已經(jīng)被劫持,所以比如我們劫持了swq.name,那么swq.name就沒有值了,所以我們給它返回值,返回值是存在訂閱者數(shù)據(jù)容器里面的 get : function(){ return swqArray[name]; } }); } })(window); swq.scanTag();//初始化,進(jìn)行雙向綁定 // 尚未實(shí)現(xiàn)的功能 ; // 1.動(dòng)態(tài)獲取需要進(jìn)行雙向綁定的name // 2.只實(shí)現(xiàn)了text文本的綁定,對(duì)象的綁定需要遞歸 // 3.臟查詢機(jī)制還未實(shí)現(xiàn),就是我們某些js后增加的需要雙向綁定的name,沒辦法進(jìn)行雙向綁定了 // 4.angular雙花括號(hào)解析表達(dá)式未實(shí)現(xiàn)<br>// 5.感覺還差得遠(yuǎn),哪位大神看到有成熟的demo記得給鏈接!!! </script> </body> </html>
demo解讀
核心其實(shí)就是js原生的defineProperty。在這之前,我們需要知道,我們?cè)诮o某個(gè)對(duì)象添加和獲取屬性和方法時(shí)其實(shí)它底層是調(diào)用了set和get方法,比如obj.name="名字",這里是調(diào)用了set方法,obj.name這里是調(diào)用了get方法。
因此,我們可以劫持js的這兩個(gè)底層方法
Object.defineProperty(obj,attribute,{set:function(newVlaue){//dosomething},get:function(){//dosomething}})
obj是我們的model對(duì)象,attribute就是我們要劫持的需要雙向綁定的name,set就是設(shè)置屬性時(shí)底層調(diào)用的方法,get就是獲取屬性時(shí)底層調(diào)用的方法因?yàn)槲覀兘俪至诉@兩個(gè)底層方法,我們可以做我們想做的事,但是同時(shí)我們也破壞了它本身的設(shè)置和獲取功能,因此我這里是把訂閱者的數(shù)據(jù)都是存在一個(gè)數(shù)組里面的,我還聲明了一個(gè)數(shù)組用來保存所有需要進(jìn)行雙向綁定的name,比較low的是我這邊是寫死的,實(shí)際情況下肯定是要?jiǎng)討B(tài)獲取所有需要雙向綁定的name的
結(jié)言
本人小菜對(duì)前端技術(shù)很感興趣,有大神路過給點(diǎn)指點(diǎn),我也可以關(guān)注下各位大神的博客,希望可以學(xué)到更多的東西?。?!謝謝
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Bootstrap與Angularjs的模態(tài)框?qū)嵗a
這篇文章主要介紹了Bootstrap與Angularjs的模態(tài)框?qū)嵗a,需要的朋友可以參考下2017-08-08angular2 ng2-file-upload上傳示例代碼
這篇文章主要介紹了angular2 ng2-file-upload上傳示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08仿Angular Bootstrap TimePicker創(chuàng)建分鐘數(shù)-秒數(shù)的輸入控件
這篇文章主要為大家詳細(xì)介紹了仿Angular Bootstrap TimePicker創(chuàng)建分鐘數(shù)-秒數(shù)的輸入控件的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-07-07詳解AngularJS跨頁面?zhèn)髦担╱i-router)
本篇文章主要介紹了詳解AngularJS跨頁面?zhèn)髦担╱i-router),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08AngularJS之自定義服務(wù)詳解(factory、service、provider)
本篇文章主要介紹了AngularJS之自定義服務(wù)詳解(factory、service、provider),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04AngularJs篇:使用AngularJs打造一個(gè)簡易權(quán)限系統(tǒng)的實(shí)現(xiàn)代碼
本篇文章主要介紹了AngularJs篇:使用AngularJs打造一個(gè)簡易權(quán)限系統(tǒng)的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,有興趣的可以了解一下。2016-12-12Angular 1.x個(gè)人使用的經(jīng)驗(yàn)小結(jié)
這篇文章主要給大家介紹了關(guān)于Angular 1.x個(gè)人使用的一些經(jīng)驗(yàn),屬于一些基礎(chǔ)入門教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-07-07