JavaScript ECAMScript5 特性get/set訪問器 實現json數據與dom對象的綁定

来源:https://www.cnblogs.com/bluebaby188/archive/2018/03/21/8616817.html
-Advertisement-
Play Games

什麼是數據綁定 數據綁定是將一個用戶界面元素的屬性綁定到一個類型/對象實例上的某個屬性的方法,實現該元素屬性和該對象實例屬性在一方數值修改時另一方的數值也隨之修改。 百度百科中的數據綁定的舉例:如果一個開發者有一個Customer類型的實例,那麼他就可以把Customer的“Name”屬性綁定到一個 ...


什麼是數據綁定

數據綁定是將一個用戶界面元素的屬性綁定到一個類型/對象實例上的某個屬性的方法,實現該元素屬性和該對象實例屬性在一方數值修改時另一方的數值也隨之修改。

百度百科中的數據綁定的舉例:如果一個開發者有一個Customer類型的實例,那麼他就可以把Customer的“Name”屬性綁定到一個TextBox的“Text”屬性上。“綁定”了這2個屬性之後,對TextBox的Text屬性的更改將“傳播”到Customer的Name屬性,而對Customer的Name屬性的更改同樣會“傳播”到TextBox的Text屬性。Windows窗體的簡單數據綁定支持綁定到任何public或者internal級別的·NET Framework屬性,同樣可以利用資料庫來簡單地綁定頁面控制項的單個屬性。

在此之前做項目的時候做過C#編寫的WPF應用程式,對其中的數據綁定有一些應用,感覺非常方便,開發效率很高。

C#WPF數據綁定舉例:

 

 先建模型類,告警類:

1 public class CAlarm                                        //告警類
2     {
3         public int iID { get; set; }                        //告警對象編號
4         public String sTsName { get; set; }           //告警對象名稱
5         public String sAlarmLevel { get; set; }       //告警級別
6         public String sDesc { get; set; }                //告警描述
7         public DateTime dAlarmTime { get; set; }         //告警時間
8     }

頁面佈局代碼:

 1 <Window x:Class="WPFBinding.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="告警列表" Height="350" Width="487">
 5     <Grid Height="311" Width="464">
 6         <ListView Name="listView1" Height="311" Width="464">
 7             <ListView.View>
 8                 <GridView>
 9                     <GridViewColumn Header="編號" DisplayMemberBinding="{Binding iID}" Width="50"></GridViewColumn>
10                     <GridViewColumn Header="對象名稱" DisplayMemberBinding="{Binding sTsName}" Width="100"></GridViewColumn>
11                     <GridViewColumn Header="告警級別" DisplayMemberBinding="{Binding sAlarmLevel}" Width="60"></GridViewColumn>
12                     <GridViewColumn Header="告警描述" DisplayMemberBinding="{Binding sDesc}" Width="100"></GridViewColumn>
13                     <GridViewColumn Header="告警時間" DisplayMemberBinding="{Binding dAlarmTime}" Width="100"></GridViewColumn>
14                 </GridView>
15             </ListView.View>
16         </ListView>
17     </Grid>
18 </Window>

然後是MainWindow的代碼:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Windows;
 6 using System.Windows.Controls;
 7 using System.Windows.Data;
 8 using System.Windows.Documents;
 9 using System.Windows.Input;
10 using System.Windows.Media;
11 using System.Windows.Media.Imaging;
12 using System.Windows.Navigation;
13 using System.Windows.Shapes;
14 using System.Collections.ObjectModel;
15 
16 namespace WPFBinding
17 {
18     /// <summary>
19     /// MainWindow.xaml 的交互邏輯
20     /// </summary>
21     public partial class MainWindow : Window
22     {
23         private IList<CAlarm> m_ilAlarms = new ObservableCollection<CAlarm>();
24         public MainWindow()
25         {
26             DateTime dt = new DateTime();
27             TimeSpan ts = new TimeSpan(0, 0, 2, 0, 0);
28 
29             m_ilAlarms.Add(new CAlarm() { iID = 1, sTsName = "對象1", sAlarmLevel = "一級告警", sDesc = "水浸檢測到漏水", dAlarmTime = dt });
30             m_ilAlarms.Add(new CAlarm() { iID = 2, sTsName = "對象1", sAlarmLevel = "二級告警", sDesc = "水浸檢測到漏水", dAlarmTime = dt = dt.Add(ts) });
31             m_ilAlarms.Add(new CAlarm() { iID = 3, sTsName = "對象2", sAlarmLevel = "一級告警", sDesc = "水浸檢測到漏水", dAlarmTime = dt = dt.Add(ts) });
32             m_ilAlarms.Add(new CAlarm() { iID = 4, sTsName = "對象3", sAlarmLevel = "三級告警", sDesc = "水浸檢測到漏水", dAlarmTime = dt = dt.Add(ts) });
33             m_ilAlarms.Add(new CAlarm() { iID = 5, sTsName = "對象2", sAlarmLevel = "一級告警", sDesc = "水浸檢測到漏水", dAlarmTime = dt = dt.Add(ts) });
34             InitializeComponent();
35 
36 
37             this.listView1.ItemsSource = m_ilAlarms;
38         }
39     }
40 
41     public class CAlarm                                //告警類
42     {
43         public int iID { get; set; }                //告警對象編號
44         public String sTsName { get; set; }            //告警對象名稱
45         public String sAlarmLevel { get; set; }        //告警級別
46         public String sDesc { get; set; }            //告警描述
47         public DateTime dAlarmTime { get; set; }        //告警時間
48     }
49 }

運行結果查看綁定:

MainWindow後端代碼使用ObservableCollection這個集合,可以雙向綁定。

private IList<CAlarm> m_ilAlarms = new ObservableCollection<CAlarm>();是定義一個雙向綁定的集合

以下是界面綁定內容

<GridViewColumn Header="編號" DisplayMemberBinding="{Binding iID}" Width="50"></GridViewColumn>

<GridViewColumn Header="對象名稱" DisplayMemberBinding="{Binding sTsName}" Width="100"></GridViewColumn>

<GridViewColumn Header="告警級別" DisplayMemberBinding="{Binding sAlarmLevel}" Width="60"></GridViewColumn>

<GridViewColumn Header="告警描述" DisplayMemberBinding="{Binding sDesc}" Width="100"></GridViewColumn>

<GridViewColumn Header="告警時間" DisplayMemberBinding="{Binding dAlarmTime}" Width="100"></GridViewColumn>

使用DisplayMemberBinding="{Binding iID}"的方式綁定

當然WPF中還有其他綁定數據到界面元素的方法和綁定類型,在此不再一一贅述。我想說的是WPF的這種綁定的方式大大提高了開發的效率。


然後在最近的一個web應用的項目中前端和後端分離,使用ajax獲取後端json數據,然後拿到數據後再通過js刷新到web頁面的dom對象相應的屬性中顯示在頁面上。

js代碼寫了一大片一大片的。好累人啊。

聯想到WPF的開發高效,現在真的好痛苦啊。

我是一個很懶偷姦耍滑的人。怎麼辦?度娘。果然有現成的:

以下是度娘百科中的內容:

AngularJS

編輯
AngularJS[1]  誕生於2009年,由Misko Hevery 等人創建,後為Google所收購。是一款優秀的前端JS框架,已經被用於Google的多款產品當中。AngularJS有著諸多特性,最為核心的是:MVW(Model-View-Whatever)、模塊化、自動化雙向數據綁定、語義化標簽、依賴註入等等。 AngularJS 是一個 JavaScript框架。它是一個以 JavaScript 編寫的庫。它可通過 <script> 標簽添加到HTML 頁面。 AngularJS 通過 指令 擴展了 HTML,且通過 表達式 綁定數據到 HTML。 AngularJS 是以一個 JavaScript 文件形式發佈的,可通過 script 標簽添加到網頁中。   看來我太low了。老土了!跟不上了!   一個簡單的例子(抄自水痕01的Angular開發(三)-關於屬性綁定與事件綁定》一文)
<script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
<
p>雙向數據綁定:</p> <input type="text" [(ngModel)]="user.name"/> <div [ngStyle]="style1">{{user.name}}</div>

js代碼:

//ts代碼
user:any = {
    name:"12345"
  }

直接搞定。

好高效啊!


 

我能不能自己寫個綁定代碼?試試:

先做一個文本框和json對象綁定的試試。

查資料發現es5的特性get/set訪問器有希望實現這個雙向綁定的功能

上代碼:

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5     <title>setAndgetTest</title>
  6     <style>
  7         html,
  8         body {
  9             width: 100%;
 10             height: 100%;
 11             overflow: hidden;
 12         }
 13     </style>
 14     <script type="text/javascript">
 15         
 16         //聲明一個json對象用來和dom對象綁定
 17         var theObj = {
 18             student_id: 100001,
 19             name: "Leao",
 20             age: 31,
 21             phoneNmb: "18618328433"
 22         };
 23 
 24         var CBinding = function(obj) {
 25             var vals = {};
 26             /*
 27             private變數,用來保存對象屬性值的集合,只保存基本類型,以json形式保存,比如vals最終可能是這樣:
 28             {
 29                 name:"Leao",
 30                 student_id: 100001,
 31                 age: 31,
 32                 phoneNmb: "18618328433"
 33             }
 34             */
 35 
 36             var doms = {};
 37             /*
 38             private變數,用來保存dom對象的集合,也就是vals的內容跟dom對象的綁定,doms最終可能是這樣
 39             {
 40                 Obj:domObj,        //domObj是name綁定的dom對象
 41                 protertyName:"value"    //protertyName是name在dom對象domObj上綁定的屬性名稱
 42             }
 43 
 44             其實可以把上面的vals修改一下:
 45                     name: "Leao",
 46                     age: 31,
 47                     phoneNmb: "18618328433"
 48             {
 49                 name:{
 50                     name: "name1",
 51                     bindingObj:{
 52                         Obj:domObj,
 53                         protertyName:"value"
 54                     }
 55                 },
 56                 student_id: 100001,//沒有綁定
 57                 age: 31,//沒有綁定
 58                 phoneNmb: "18618328433"//沒有綁定
 59             }
 60             */
 61 
 62             this.bInit = false;//是否被初始化
 63 
 64             if (null != obj) {
 65                 var names = Object.getOwnPropertyNames(obj);//獲取obj的所有屬性名
 66                 var sFieldName = "";
 67 
 68                 if (null != names && 0 < names.length) {
 69                                 var iIndex = 0, iCount = names.length, val = null;
 70 
 71                     for (iIndex = 0; iIndex < iCount; iIndex++) {
 72                         sFieldName = names[iIndex];
 73                         val = obj[sFieldName];
 74                         vals[sFieldName] = val;
 75                         doms[sFieldName] = {
 76                             Obj: {},        //保存dom對象
 77                             bSet: false,        //是否被綁定
 78                             protertyName: ""    //dom對象的屬性名稱
 79                         };
 80 
 81                         Object.defineProperty(this, sFieldName, {
 82                             value: val,
 83                             configurable: true,    //能否使用delete、能否需改屬性特性、或能否修改訪問器屬性、,false為不可重新定義,預設值為true
 84                             enumerable: true,    //對象屬性是否可通過for-in迴圈,flase為不可迴圈,預設值為true
 85                             writable: true,        //對象屬性是否可修改,flase為不可修改,預設值為true
 86                         });
 87                     }
 88                 }
 89             }
 90         
 91             this.bInit = true;//被初始化
 92 
 93             /*
 94                 綁定方法,
 95                 @domObj,綁定的dom對象
 96             */
 97             this._binding = function(domObj) {//
 98                 if (null != domObj) {
 99                     var sName = domObj.name || domObj.id;//綁定按照name或id進行匹配
100 
101                     if (null != sName && 0 < sName.length) {
102                         var theVal = vals[sName];
103                         var theDom = doms[sName];
104 
105                         if (null != theVal && null != theDom) {    //查看是存在sName的的值和綁定對象
106                             var fieldName = "value";    //綁定的dom對象屬性名稱,此處只實現了value以後可以在本方法中添加一個參數用來表示屬性名稱
107 
108                             theDom.Obj = domObj;        //保存綁定的dom對象引用/指針
109                             theDom.bSet = true;        //設置綁定標誌
110                             theDom.protertyName = fieldName;
111                             theDom.Obj[fieldName] = theVal;    //直接賦值
112 
113                             Object.defineProperty(this, sName, {
114                                 get: function() {    //重寫讀取訪問器
115 
116                                     var theDom = doms[sName];
117                                     var reValue = null;
118 
119                                     console.log("get:");
120                                     console.log(this);
121                                     if(theDom.bSet){
122                                         reValue = theDom.Obj[fieldName];//直接讀取dom對象的fieldName屬性值
123                                     }
124                                     else{
125                                         reValue = vals[sName];        //未綁定使用保存值
126                                         console.log(sName + "屬性未綁定,使用保存值");
127                                     }
128                                     return reValue;
129                                 },
130                                 set: function(val) {//重寫設置訪問器
131                                     var theDom = doms[sName];
132 
133                                     vals[sName] = val;//保存值
134                                     console.log("set:");
135                                     console.log(this);
136                                     if(theDom.bSet){
137                                         theDom.Obj[fieldName] = val;//直接設置dom對象的fieldName屬性值
138                                     }
139                                     else{
140                                         console.log(sName + "屬性未綁定,使用保存值");
141                                     }
142                                 }
143                             });
144                         }
145                     }
146                 }
147             }
148         }
149 
150         CBinding.prototype.binding = function(domObj) {    //定義綁定原型方法
151             this._binding(domObj);//調用定義的方法
152         };
153 
154         function bindingObj(domObj, dataObj) {    //dom對象和json對象綁定,返回新的綁定對象
155             var rObj = null;
156             if (null != domObj && null != dataObj) {
157                 if (null == dataObj.bInit) {
158                     rObj = new CBinding(dataObj);
159                 } else {
160                     rObj = dataObj;
161                 }
162                 rObj.binding(domObj);
163             }
164 
165             return rObj;
166         }
167 
168         	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、v-if指令:判斷指令,根據表達式值得真假來插入或刪除相應的值。 2、v-show指令:條件渲染指令,無論返回的布爾值是true還是false,元素都會存在在html中,只是false的元素會隱藏在html中,並不會刪除. 3、v-else指令:配合v-if或v-else使用。 4、v-for指 ...
  • 通過ajax傳輸,跨域不能使用 dataType: 'jsonp',不然後端無法獲取文件,用 jsonp: 'callback' ...
  • 轉自:https://www.cnblogs.com/e0yu/p/7219930.html?utm_source=itdadao&utm_medium=referral#undefined 使用 angular JS 的時候,把 angularJS 放到文件底部,在渲染頁面的時候,會出現閃一下的情 ...
  • geoCoordMap = { '上海': [121.4648,31.2891], '佛山': [112.8955,23.1097], '保定': [115.0488,39.0948], '蘭州': [103.5901,36.3043], '包頭': [110.3467,41.4899], '北京'... ...
  • 一、賬號註冊 分別https://www.gitbook.com和https://github.com/註冊賬號。 二、github上新建一個倉庫如 https://github.com/wjf444128852/blog 1、gitbook內新建一本書籍, 2、模板選項中選擇GITHUB,如下圖 ...
  • 註釋 1. // This is an in-line comment. 2. /* This is a multi-line comment */ 七種data types(數據類型) undefined(未定義), null(空), boolean(布爾型), string(字元串), symb ...
  • 使用JS和CSS3實現360度立體抽獎盒 效果圖: 下麵為大家附上代碼喲,定製屬於你們的抽獎盒: 如有錯誤,請聯繫指正,非常感謝!!! ...
  • JS實現簡單的幸運抽獎頁面 效果圖: 圖片素材 : 代碼如下,複製即可使用: 如果您有更好的方法或更多的功能,可以和我們大家一起分享哦,如有錯誤,歡迎聯繫我改正。非常感謝!!! ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...