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 上,右侧附加不附加问题都不大
思路如此,代码你可以先尝试写下