基於jquery的表格動態建立,自動綁定,自動獲取值

最近剛加入GUT項目,學習了不少其餘同事寫的代碼,感受受益不淺。html

在GUT項目中,常常會碰到這樣一個問題:動態生成表格,包括從數據庫中讀取數據,並綁定在表格中,以及從在頁面上經過jQuery新增刪除表格。以下所示:jquery

 

在實現過程當中,開發人員常常採用以下方式來實現:web

1)          在前臺,經過js生成表格行的html字符串,而後經過jquery的after方法加到表格底部。ajax

2)          在後臺,讀取數據庫,而後生成表格的html字符串,而後傳遞給前臺渲染sql

3)          這樣作的好處,主要是能夠實現無刷新的操做表格的效果數據庫

這種實現方式存在以下些問題(固然,我的意見,僅做技術交流^_^):json

1)          代碼重複。前臺寫了一遍表格建立的js,後臺又寫了一遍oracle

2)          字符串拼接。後臺建立時,會大量使用字符串的拼接來實現表格的htnl字符串,不只影響效率,並且不容易debug。好比少了個引號等,不容易找出來。(關於效率問題,由於字符串在.net中是恆定的,因此若是作不少次字符串的拼接,將形成資料的浪費和效率地下)ide

3)          綁定表格數據與獲取表格數據要寫不少代碼,假設表格有10列字段,就要寫關於這10列的數據怎麼獲取,以及怎麼綁定會表格中的。函數

4)          開發人員常常在.aspx頁面中寫數據庫的訪問操做,這樣也不符合MVC分離關注點的精神。若是項目換成別的數據庫,好比oracle(按照項目的數據量來看,將來不排除換數據庫的可能性),那麼屆時開發人員將須要滿項目中數據庫相關的語句來修改。

--------------------------------------分割線------------------------------------------

如前所述,能夠從以下幾個思路來思考:

1)          可否只在頁面上編寫一些js腳本,來創造表格,而在後臺只是提供要建立表格數據便可。也就是說後臺獲取數據,而後交給前臺去調用js函數建立表格。這樣就能夠避免先後臺都寫兩次的問題了。並且也不會在後臺用大量的字符串拼接來建立表格的html字符串。

2)          可否換種方式,不要經過字符串拼接的方式來建立表格?好比jquery.html()?

3)          可否提供一種統一的建立表格,綁定表格,獲取表格數據的方法呢?以避免每次都要寫那麼多代碼來建立表格。

基於上述思路,我開發了一個demo,實現了用較少的代碼動態建立表格,綁定表格數據,獲取表格數據,並保存到數據庫中。並且代碼是能夠複用的。

--------------------------------------分割線------------------------------------------

前期準備:

1)          建立數據庫test,添加表person

 

2)          建立Entities層,DAL層,BLL層

 

Entities層(經過T4模板自動生成)

using System;

using MyBasicLib;

using MyBasicLib.Data.ORMLiteNew;

namespace ATMB.DCMS.Entities

{

    /// <summary>

    ///

    /// </summary>

  [Serializable]

    [Table(TableName="person" ,KeyName="ID")]

    public partial class person:BaseTable

    {

      /// <summary>

        ///

        /// </summary>

        public person()

        {

        }

      #region Public Properties

      /// <summary>

        ///

        /// </summary> 

        public  override  String ID

        {

            set ; get ;

        }

      /// <summary>

        ///

        /// </summary> 

        public  String name

        {

            set ; get ;

        }

      /// <summary>

        ///

        /// </summary> 

        public  String age

        {

            set ; get ;

        }

      /// <summary>

        ///

        /// </summary> 

        public  String sex

        {

            set ; get ;

        }

      /// <summary>

        ///

        /// </summary> 

        public  String location

        {

            set ; get ;

        }

 

      #endregion

  }

}

DAL層,實現了新增,批量新增,刪除,獲取全部數據的幾個簡單的方法

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using ATMB.DCMS.Entities;

using MyBasicLib.Data.ORMLiteNew;

 

namespace DAL

{

    public class PersonDA

    {

        public void Add(person p)

        {

            using (var dc = new DataContext())

            {

                dc.Insert(p);

                dc.SubmitChanges();

            }

        }

 

        public void Add(List<person> ds)

        {

            using (var dc = new DataContext())

            {

                foreach(var p in ds)

                {

                    dc.Insert(p);

                }

                dc.SubmitChanges();

            }

        }

 

        public void Delete()

        {

            using (var dc = new DataContext())

            {

                dc.Delete<person>(p => !SqlMethods.IsNull(p.ID));

                dc.SubmitChanges();

            }

        }

 

        public List<person> GetList()

        {

            using (var dc = new DataContext())

            {

                return dc.GetTable<person>().ToList();

            }

        }

 

    }      

}

BLL層

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using ATMB.DCMS.Entities;

using DAL;

 

namespace BLL

{

    public class PersonBLL

    {

        PersonDA da;

 

        public PersonBLL()

        {

            da = new PersonDA();

        }

 

        public void Add(List<person> ds)

        {

            da.Delete();

            da.Add(ds);

        }

 

        public List<person> GetList()

        {

            return da.GetList();

        }

           

    }

}

備註:數據庫底層訪問使用Linq,換成oledb等其餘方式只要修改DAL層就能夠了。

3)          經過js實現表格的動態建立

第一步:定義表格

 

這裏有幾個地方要注意下:

第一:頁面上添加的表格中,我添加了兩個tr,一個是顯示出來的tr,帶有「新增」的圖標。另外一個是隱藏的,用來做爲新增的行的模板。這樣,不容易出錯,並且避免經過字符串來建立。

第二:顯示的tr中,設置了一個叫」TargetTR」的class,這個是用來搜索表格的全部行的,後面會用到。

第三,每一個td中,新增了一個tag屬性,與數據庫表的實際字段對應,用來自動獲取和綁定表格數據。

第四,tr模板的每一個input的id(或者其餘須要替換的屬性)都定義爲XXX_x,_x後綴是用來替換的。好比新增了一個tr,序號爲3,便要替換tr中每一個input的_x後綴爲_3。諸如此類。

第二步:實現新增和刪除表格行的js方法

 

ChangeAttr實現以下:

 

changeAttr主要是實現替換input的帶_x結尾的屬性爲具體的序號。

以上實現了在頁面上對錶格行的新增和刪除。經過模板的定義,咱們無需在js寫新增的tr的html字符串。這樣能夠最大可能的減小錯誤發生的可能性。由於字符串的可讀性比較差,debug比較難。

接下來,要實現後臺獲取表格數據,而後經過上述的幾個js腳本動態生成表格。

首先介紹下實現的思路

 

第一步,看下.ashx中的實現

 

 

Ashx中的實現很簡單,就是根據前臺的請求,進行相應的操做,而後返回結果(json)給前臺

第二步:前臺經過ajax訪問.ashx,獲取表格數據

 

 

Success時,會以json的格式返回表格的數據(好比person的集合),而後前臺會解析這個json數據,並建立表格出來。

 

BindTable的實現很簡單,首先看下共有多少條數據,而後屢次調用add_tr方法,添加tr。(由於第一個tr是默認存在的,因此只要調用json.length-1次)

接下來即是該功能的核心了,綁定表格的數據。這裏只須要調用一個函數就能夠了bindTableValue,其實現以下

 

這個函數能夠實現任意表格的數據綁定。徹底能夠複用。固然還存在些缺陷。本文最後會做以說明。

以上遍實現了從數據庫獲取值,而後動態繪製表格的過程。整個過程沒有針對特定的表格來實現,因此代碼是能夠複用的。這個實現過程還有個好處是:分離關注點。對於表現層(前臺,web層),只關心於根據數據來作相應的展示,而不關心數據是怎麼來的(來自於sql,仍是oracle?採用何種方式)。而BLL層負責根據用戶的請求返回數據。關注於業務邏輯的處理。這樣的實現方式,不會在前臺寫任何的sql語句。代碼看起來比較簡潔。

最後,實現將修改後的表格數據保存回數據庫中。這就比較簡單了

 

當點擊保存時,調用save方法。Save方法中的核心是第一句:

 

getTableValue的實現爲:

 

這樣,開發人員一樣不用寫任何代碼,即可以實現數據對象的自動獲取。該代碼是能夠複用的。

--------------------------------------分割線------------------------------------------

總結:

  1. 上文以可複用,可擴展,分離關注點的方式實現了表格的動態繪製,數據的自動綁定和自動獲取。並且用戶的代碼量相較以往減小了很是多。
  2. 自動綁定和獲取的方法還存在些不足,由於當前版本的實現只是基於string類型的。未考慮datetime,bool,int等類型。可是根據分離關注點的原則(或者依賴倒置原則),咱們一樣能夠將該部分邏輯分離出來,交給專門處理數據類型的類來處理。而後保持原有的邏輯不變。下來我會繼續改進。
  3. 該方法一樣適用於表單數據的保存和綁定.
  4. 心得體會:Less Code, Less Copy, More ReUseable, More Flexiable and More OO。
相關文章
相關標籤/搜索