javascript - 動態創建對象,動態加數據
問題描述
如圖:1.左邊兩側的表格都是點擊 上邊“新增”按鈕動態添加出來的。點擊左側表格某一行,可以在右側創建表格(任意多少行都行),左右是一對多關系。2.想在左側新增行的時候,創建一個獨立對象(意思就是每個行對應的對象都不一樣), 然后右側點擊新增后,新建出來的行,是帶幾個下拉菜單的,用戶選完之后,就會點擊開始填報,在點擊開始填報按鈕時,需要把右邊的數據和左邊的數據,都存進左邊某一行的對象里。(左邊每一行對應一個對象)3.左右表格上方都有’刪除’按鈕,如果點擊左側’刪除’按鈕,那么這一行的存儲對象就被刪了,于是右邊和它對應的數據也沒餓了。如果選中右側某一行,點擊’刪除’,那么只在左側的對象里刪除右側這一行的數據存儲。
框架:用了Bootstrap jQuery
下面是代碼只有我說的添加tr刪除tr的功能實現。并沒有創建對象和添加數據,有沒有老哥有思路的,在線等,急!!!代碼:
<p class='col-md-5 clearfix'><button class='button1'>新增</button><button class='button1_del'>刪除</button><table border='1px solid #000' class='text-center'> <thead class='zType_thead text-center'><tr> <th></th> <th>納稅人識別號</th> <th>納稅人名稱</th></tr> </thead> <tbody class='zType_tbody'> </tbody></table> </p> <p class='col-md-offset-1 col-md-5'><button class='button2'>新增</button><button class='button2_del'>刪除</button><button type='submit'>開始填報</button><form method='post'> <table border='1px solid #000'><thead> <tr class='zType_table_th'><th>計算期類型</th><th>期間</th><th>征收方式</th> </tr></thead><tbody class='zType_all'></tbody> </table></form> </p>
js代碼:
//點擊選中右側表格的某一行$(’.zType_all’).on(’click’,’tr’,function(){//點擊某一行 此行背景色改變,其他行恢復白色。點擊的那一行添加了name屬性,然后刪除其他tr的name值,為的是之后聯系起來,有個name屬性作為橋梁,比如刪除,就可以在刪除掉對應帶有name值的tr$(’.zType_all’).children().css({'background':'#fff','color':'#000'}).removeAttr(’name’); $(this).css({'background':'#bfaadc','color':'#000'}); if(!$(this).attr(’name’)){ $(this).attr('name',’zType_tr_checked1’); }})//右側刪除按鈕 點擊刪除帶有name的tr$(’.button2_del’).on(’click’,function(){ $(’tr[name=zType_tr_checked1]’).remove();})//左側添加按鈕$(’.button1’).on(’click’,function(){ $(’.zType_tbody’).append(’<tr><td><span class='glyphicon glyphicon-chevron-right'></span></td><td><input type='text' name='shibiehao'></td><td><input type='text' name='mingcheng'></td></tr>’);})//選中左側表格的tr$(’.zType_tbody’).on(’click’,’tr’,function(){ //依然還是點擊某一行 此行背景色改變,其他行恢復白色。點擊的那一行添加了name屬性,然后刪除其他tr的name值,為的是之后聯系起來,有個name屬性作為橋梁,比如刪除,就可以在刪除掉對應帶有name值的tr $(’.zType_tbody’).children().css({'background':'#fff'}).removeAttr(’name’); $(this).css({'background':'#bfaadc'}).children().eq(0).children() if(!$(this).attr(’name’)){ $(this).attr('name',’zType_tr_checked2’); }})//點擊左側刪除按鈕,刪掉左側選中的tr$(’.button1_del’).on(’click’,function(){ $(’tr[name=zType_tr_checked2]’).remove();})
問題解答
回答1:簡單說下我的思路:每個 DOM 結構維護一個數據對象,假設你的 HTML 結構為(emmet語法):
.app-test > .col-md-5.app-test-taxpayer + .col-md-5.app-test-report
那么:
上面分為三個組件
.app-test 負責維護所有納稅人數據(即左側表格);
左側列表的每個 tr 維護對應納稅人的數據(即右側表格);
兩側的所有 tr 都可以視為一個小的組件 —— 麻雀雖小五臟俱全;
總結出為:整個功能組件 > 左側 tr 組件 + 右側 tr 組件;
你可以理解為父子組件傳值;
大致實現如下:首先,兩個表格屬于一個功能模塊,假設為 TaxesReport:
(function($){ // 左側 tr 組件 var TaxesReportTaxpayer = function(trs){return this; };// 右側 tr 組件 var TaxesReportReporter = function(trs, taxpayer){// 當前納稅人的報表,對應右側的列表條目this.reports = []; return this; };// 一個獨立的功能模塊 var TaxesReport = function(element){// 全部納稅人,即左側列表對應的數據源this.taxpayers = [];// 當前選擇的納稅人,即左側列表中的紫色高亮行this.currentTaxpayer = null; };// 應用實例 - 假設: .test > .col-md-5.clearfix var trDemo = new TaxesReport( $(’.app-test’) ); })(jQuery);
TaxesReportTaxpayer 和 TaxesReportReporter 都需要傳入一個 TaxesReport 實例,用于【子組件調用父組件】 方法或數據
點擊左側新建按鈕新建納稅人:
// TaxesReport() 中var _that = this, $taxpayerAdd = $(’.button1), $taxpayerList = $(’.zType_tbody’); // 新建納稅人 $taxpayerAdd.on(’click’, function(){ // 實例化納稅人組件 var taxpayer = new TaxesReportTaxpayer(_that);// 增加行 $taxpayerList.append( taxpayer.item );// 新增數據 _that.setTaxpayer( taxpayer.data );// 自動高亮 if(!_that.currentTaxpayer) {_that.currentTaxpayer = taxpayer; }});
右側新增納稅人的報表類型,如:
// TaxesReport() 中var _that = this, $reportAdd = $(’.button2’), $reportList = $(’.zType_all’); // 新增納稅人報表類型$reportAdd.on(’click’, function(){ // 請從左側選擇一個納稅人 if( !_that.currentTaxpayer ) {console.log(’請從左側選擇一個納稅人’);return; }// 實例化報表組件 var report = new TaxesReportReporter(_that);// 增加行 $reportList.append( report.item );// 增加數據 // _that.currentTaxpayer.setReport(report.data) _that.currentTaxpayer.item.trigger(’setReport’, report.data);// 查看是否添加成功 console.log( _that.currentTaxpayer.reports );});
刪除的時候,除了刪除對應的 tr 結構,刪除 tr 對應的數據,涉及到的兩個數據對象(左側的 taxpayers 和 右側的 reports) 都是數組結構,你可以為自定義鍵名方法,為新的實例(納稅人或報表)創建唯一標識,并使用 <tr data-identify='唯一標識'>···</tr> 建立起取值參數。
鑒于你可能都是靜態數據(非從數據庫中取出的帶有主鍵標識的數據),且可能刪除數組中的任意一個條目進而導致數組下標丟失,所以,最好的方法是建立一個可創建不重復值的方法,用以給生成的組件(左側或右側)生成并添加一個唯一標識。
回答2:產生一個數據緩存,在 key-model 的形式保存數據,右邊的 model 里有一個 children 保存對應的右側數據
左側切換的時候,直接從 key-model 數據緩存里找到對應的 model.children,重繪右側的列表
左側添加刪除的時候對應的從 key-model 數據緩存里添加刪除就好
右側添加刪除的時候也是一樣的,這個時候可以對找到對應的 model.children
由于使用 jQuery,jQuery 可以通過 data() 把數據附加到 DOM 上,所以上述 key-model 可以直接采用之種形式把每個 model 附加到每行(左側)的 DOM 上,右側附加不附加問題都不大
思路如此,代碼你可以先嘗試寫下
