今天项目中大量的地方使用了datatable .各处使用大同小异。然后就像把data 使用上的一些关键地方全部抽离出来。让在我现在的使用中能更简单。
首先 datatable base view 中:
1. 定义默认的配置项:
defaultOptions: { autoWidth: false,//自动宽度 destroy: true,//自动destory filter: false,//不使用自带的过滤 info: true,//显示table 相关信息,页数等 ordering: true,//启用排序 lengthChange: false,//不允许修改每页的显示数 paginate: true,//启用分页 serverSide: true,//启用服务器数据 ajax: null,//ajax 请求数据 data: null,// 需要显示的数据,和ajax 必须有已给有数据 displayLength: 10,//每页显示的数据条数 columns: []//table 的列。 },
2.这里默认的 配置项 在 view 的 initialize 的时候会和 用户自定义的属性进行合并。
initialize: function(options) { var view = this; view.defaultOptions = $.extend({}, view.defaultOptions, options);// 合并用户自定义的options if (view.defaultOptions.ajax == null && view.defaultOptions.data == null) { throw new Error('dataTable dataSource is null !'); } // if (view.defaultOptions.columns.length == 0) { // throw new Error('dataTable settings columns is mull!'); // } if (view.defaultOptions.ajax == null && view.defaultOptions.data != null) { view.defaultOptions.serverSide = false; } },
3. 在view 的render 的时候 需要展示出来数据。
render: function(){ var view = this; view.$el.html(view.template()); view.defaultOptions.columns = $.map(view.columns, function (colData) { return { name: colData.name, title: colData.title, orderable: colData.orderable, className: colData.className, visible: colData.visible, width: colData.width, field: colData.field, sortField: colData.sortField, data: colData.data, render: function ( data, type, full, meta ) { return view.getTableColumns(data,type,full,meta,colData); } }; }); view.dataTable = view.$el.find('table.MnBaseDataTable').DataTable(view.defaultOptions); return this; },
这里循环了view.columns 这个变了赋值时在调用datatable render 的地方赋值进去的。 其中coldata 就是一个个的column 配置对象。如下:
var statusColumn = { title: 'STATUS',// table 列表头显示文字 data: 'Status__c',//数据加载取ajax 回来数据的哪个值 type: 'STRING',//数据渲染的方式,详见数据渲染 columnName: 'status',//列名字 sortField: 'Status__c',//拍序列 visible: true,//是否显示 orderable:false,//是否允许排序 className:'',//样式名字。用于渲染的时候 加样式 editable: false,//是否可编辑 defaultContent: '',//默认显示,数据不存在的时候显示值 actionOptions:[//这个是专门针对Action 这类的渲染必须的配置。 {displayValue:'Delete',className:'delete'} ] };
上面的column 对象中必须要的几个: title, data,type,editable, 这几个是必须要的。
其中 type 有如下几种:Data、DataTime, Textarea, Currency,Percent,Boolean,Renfrencence,PickList,Action,其他类型,具体的区别见下面的数据渲染。
数据渲染:
根据传进来的 column 对象 type + editeable来确认该渲染成具体的页面上的样式。这里只是贴一段代码:
if (colData.type == 'DATE' || colData.type == 'DATETIME' ) { if (view.mode == 'edit' || editable) { var formattedDate = (data) ? moment.utc(data).format(MnGPMDateFormat) : ''; result = '<div class="slds-input-has-icon editDataPicker slds-input-has-icon--right">' +' <svg aria-hidden="true" class="slds-input__icon pickerIcon" data-lang="'+meta.row+'" slds-icon-text-default ">' +' <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="'+sldsUrl+'/assets/icons/utility-sprite/svg/symbols.svg#event"></use>' +' </svg>' +' <input class="slds-input haspicker haspicker'+meta.row+' dateInput textBorder editText'+meta.row+'" type="text" value="'+formattedDate+'" readonly="" />'; +'</div>'; } else { result = (data) ? moment.utc(data).format(MnGPMDateFormat) : ''; result = '<div class="' + className + '">' + result + '</div>'; } }
这里根据传进来的type 确定为渲染为时间样式。 先格式化时间 -- > 判断是否可编辑,如果可编辑那么,渲染出来的结果就是input + Icon 图标可以编辑的文本框中显示时间日期。否则以文本的方式显示时间。
同理其他的类型都是这样处理的。
到此我们的处理就完成,在最后交给了datatable columns 让datatable 来给我们处理。
简单说使用:
1.调用的view中:
1.第一步初始化datatable 的参数以及basedatatable view. 见 下面代码的 initiallize.
2.view render 的时候 初始化 BaseDataTable 的view 并将columns 传给BaseDataTable 开始渲染。见代码 render .
3.其他,getData 方法也是必须要的,是ajax 请求数据的必要方法,按照自己需要的逻辑来加载数据 最后调用callback 回掉交给datatable 来渲染。
initialize: function(options) { var view = this; //......其他业务 var settings = view.getDataTableSettings(); view.tableView = new MnAdvDataTableBaseView(settings); }, render: function() { var view = this; //......其他业务 view.tableView.setElement(view.$el.find('.MnAdvDataTableContainar')); view.tableView.columns = view.columns;// 赋值给datatable 的columns view.tableView.render(); return view; }, getDataTableSettings: function(){ var view = this; var checkboxColumn ={ width: '5%', title: '<label class="slds-checkbox" for="select-all"><input name="checkbox" type="checkbox" id="select-all" class="check-all" /><span class="slds-checkbox--faux"></span><span class="slds-form-element__label slds-assistive-text">select all</span></label>', data: null, type: 'BOOLEAN', columnName: 'checkbox', sortField: '', visible: true, editable: true, orderable: false }; //......定义其他colum view.columns =[checkboxColumn, ........]; var settings = { ajax: function (data, callback, settings) { view.getData(data, callback, settings); }, displayLength: view.filter.pageSize, order:[] }; return settings; }, getData: function(data, callback, settings){ var result = //......请求后台数据的方法 返回json 。 callback(result) }
现在我们的 option cloumns 是从后台 表的 fieldset 中读取出来数据,然后照上面 column 对象配置 放到datatable的columns 中统一渲染:
1.配置filedset
在.object 中 的新增 fieldsets 节点:
<fieldSets> <fullName>AdvSimulationPriceChange</fullName> <description>Fields will be displayed in the AdvSimulation Price Changes tab</description> <displayedFields> <field>MnCountryPriceType__r.PriceTypeName__c</field> <isFieldManaged>false</isFieldManaged> <isRequired>false</isRequired> </displayedFields> <displayedFields> <field>MnCountryProductSKU__r.CurrentStatus__c</field> <isFieldManaged>false</isFieldManaged> <isRequired>false</isRequired> </displayedFields> <displayedFields> <field>MnProductSKU__r.Strength__c</field> <isFieldManaged>false</isFieldManaged> <isRequired>false</isRequired> </displayedFields> <displayedFields> <field>MnProductSKU__r.Name</field> <isFieldManaged>false</isFieldManaged> <isRequired>false</isRequired> </displayedFields> <displayedFields> <field>MnProductSKU__r.PackSize__c</field> <isFieldManaged>false</isFieldManaged> <isRequired>false</isRequired> </displayedFields> <label>AdvSimulation Price Change Fields</label> </fieldSets>
其中label 以及 fullName description 是必须要的。salesforce 前台查询的时候就是根据fullName 来查询的。
在fieldSets 中可以有<availableFields> 和<displayedFields> 前者是加进去 但是不显示,salesforce页面中能在左边框中看到。 后者是显示在右边的。 前者前台是查询不出来的,只有displayedField才能查出来。可以在页面中两边的互相拖动来修改availableFields。
前台js 查询
需要用到的collection:MnFieldSetCollection 将这个collection require 进来。以下是查询方法:
loadFieldSet: function() { var view = this; var priceEventFieldSet = new MnFieldSetCollection({objectName: 'MnAdvSimulationPriceEvent__c',fieldSetName: 'AdvSimulationPriceChange'}); priceEventFieldSet.fetch({ success: function(collection, response, options) { //console.log(JSON.stringify(response)); }, error: function(m, r, o) { appRouter.showError('Failed to load MnAdvSimulationPriceEvent fiedSet.', error.message, error); } }); },
objectName : 查询的fiedset所在的object .
fieldSetName: 上面在object 中配置的fieldSets 中的fullName.
注意点: 如果是查询出来用做datatable 显示的话,那么的注意这个方法是需要执行时间的,在还没进sucess 之前datatable就已经render 完成了,这个需要按照自己的逻辑来render datatable 的view,或者render 当前的view.
fixed columns
这个是属于datatable的插件一种,需要引入jquery.fixedColumns。
使用如下:
在datatable 的setting 中配置以下配置----必须都要
scrollX: true, scrollCollapse: true, fixedColumns : {leftColumns:0, rightColumns:6};
注意点:fixedColumns 对象中leftColumns 表示从左边开始起有几列是fixed 的,right 是右边。 在1.10 版本中设定右边的时候 leftColumns 必须设置为0 不然左边会有一列也是fixed 的。
fixedColumns 必须要设置好datatable的外部容器的宽度,不能是百分比,最好是根据js来动态设置。
fixedColumns 会产生三个table 用漂浮的形式来展示的,三个table 都是一样的,只不过显示的东西不一样,所以注意点就是在用js 给某个 文本框等设置值的时候 一定要全部设置,不然可能会导致设置了页面上看不到效果。