本篇文章為大家展示了如何在ABP框架中使用BootstrapTable組件,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
在成都網(wǎng)站建設(shè)、成都網(wǎng)站制作中從網(wǎng)站色彩、結(jié)構(gòu)布局、欄目設(shè)置、關(guān)鍵詞群組等細(xì)微處著手,突出企業(yè)的產(chǎn)品/服務(wù)/品牌,幫助企業(yè)鎖定精準(zhǔn)用戶,提高在線咨詢和轉(zhuǎn)化,使成都網(wǎng)站營(yíng)銷成為有效果、有回報(bào)的無錫營(yíng)銷推廣。創(chuàng)新互聯(lián)專業(yè)成都網(wǎng)站建設(shè)十多年了,客戶滿意度97.8%,歡迎成都創(chuàng)新互聯(lián)客戶聯(lián)系。一、關(guān)于ABP
ABP是“ASP.NET Boilerplate Project (ASP.NET樣板項(xiàng)目)”的簡(jiǎn)稱,它是一個(gè)成熟的開源框架,基于DDD+Repository模式,自帶Zero權(quán)限和認(rèn)證模塊,避免了從零開始搭建框架的煩惱。關(guān)于ABP的框架優(yōu)勢(shì)就此打住,因?yàn)檫@樣說下去要說三天三夜,脫離文本主題。
點(diǎn)擊CREATE MY DEMO按鈕,系統(tǒng)會(huì)自動(dòng)為你生成演示地址
進(jìn)入對(duì)應(yīng)的Demo URL
使用演示的用戶名和密碼登陸進(jìn)去
可以看到Zero模塊的實(shí)現(xiàn)效果。
二、jTable在ABP中的運(yùn)用
如果你下載ABP的源碼,并且選擇的是混合開發(fā)模式(ABP提供了兩種開發(fā)模式,一種是基于MVVM的Angular.js的模式;另一種就是MVC+jQuery的混合開發(fā)模式),如下圖:
當(dāng)你Down下來源碼之后你就會(huì)發(fā)現(xiàn),ABP的源碼里面的UI部分的表格都是使用jTable去實(shí)現(xiàn)的。為什么會(huì)用jTable?原因很簡(jiǎn)單,jTable是ABP的作者kalkan寫的一款開源插件,自己寫的肯定用自己的東西嘍。下面jTable的效果來一發(fā)。
來一個(gè)jtable的父子表:
如果是不帶父子表的簡(jiǎn)單表格,其實(shí)jTable的效果其實(shí)還行,可是加上一些復(fù)雜的功能之后,那一片片藍(lán)色的區(qū)域不忍直視,并且jTable的api還有待完善,很多需要的功能都需要自己去實(shí)現(xiàn),于是就接到了將所有的表格組件換成BootstrapTable的需求,才有了今天的主題:在ABP中封裝BootstrapTable。
三、Bootstrap Table在ABP中的封裝
接到需求,博主各種百度、各種谷歌,都找不到Bootstrap Table組件在ABP中的封裝,有的只是在ABP的項(xiàng)目里面簡(jiǎn)單的用傳統(tǒng)的方式去初始化組件,這并不是博主想要的。說到這里不得不說一下,如果你使用ABP開發(fā)的過程中遇到一些難題,你會(huì)發(fā)現(xiàn)很難從百度里面搜索到相關(guān)答案,谷歌里面有時(shí)能找到,但大部分都是英文社區(qū),所以如果你英文較弱,在查找資料上面會(huì)很吃虧,有時(shí)一個(gè)簡(jiǎn)單的配置問題需要折騰很久。
1、jTable在ABP項(xiàng)目里面的初始化
首先來看看jTable在一般的ABP項(xiàng)目里面是如何初始化的。比如我們?cè)贏pplication里面有一個(gè)如下的接口和實(shí)現(xiàn)
public interface IRequisitionAppService : IApplicationService { Task<PagedResultDto<RequisitionListDto>> GetRequisitionListAsync(GetRequisitionListInput input); } [AbpAuthorize(OrderAppPermissions.Pages_Order_Requisition)] public class RequisitionAppService : AbpZeroTemplateAppServiceBase, IRequisitionAppService { private readonly IRepository<Requisition, long> _requisitionRepository; public RequisitionAppService(IRepository<Requisition, long> requisitionRepository) { _requisitionRepository = requisitionRepository; } public async Task<PagedResultDto<RequisitionListDto>> GetRequisitionListAsync(GetRequisitionListInput input) { var query = _requisitionRepository.GetAll() .WhereIf(input.Status != null, w => (int)w.Status == input.Status.Value) .WhereIf( !input.Filter.IsNullOrWhiteSpace(), u => u.No.Contains(input.Filter) || u.Remark.Contains(input.Filter) ); var count = await query.CountAsync(); var list = await query .OrderBy(input.Sorting) .PageBy(input) .ToListAsync(); var dtos = list.MapTo<List<RequisitionListDto>>(); return new PagedResultDto<RequisitionListDto>( count, dtos ); } }
然后我們前端有一個(gè)頁面的列表數(shù)據(jù)從這個(gè)接口GetRequisitionListAsync()獲取
<div class="portlet-body"> <div id="dataListTable"></div> </div> (function () { $(function () { var _$dataListTable = $('#dataListTable'); var _service = abp.services.app.requisition; _$dataListTable.jtable({ paging: true, sorting: true, selecting: true, actions: { listAction: { method: _service.getRequisitionListAsync } }, fields: { id: { key: true, list: false }, details: { width: '1%', sorting: false, edit: false, create: false, listClass: 'child-opener-image-column', display: function (detailData) { var $img = $('<img class="child-opener-image" src="/Common/Images/list_metro.png" title="申購(gòu)明細(xì)" />'); $img.click(function () { _$dataListTable.jtable('openChildTable', $img.closest('tr'), { title: "申購(gòu)明細(xì)", showCloseButton: true, actions: { listAction: { method: _service.getRequisitionDetailListByIdAsync } }, fields: { materialClassParentNameAndName: { title: app.localize('MaterialClassName'), width: '8%' }, materialInfoTypeNo: { title: app.localize('TypeNo'), width: '5%' }, materialInfoLengthDisplayName: { title: app.localize('LengthDisplayName'), width: '3%' }, materialInfoWeight: { title: app.localize('Weight'), width: '5%', display: function (data) { return data.record.materialInfoMinWeight + '-' + data.record.materialInfoMaxWeight; } }, materialInfoMouldTypeDisplayName: { title: app.localize('MouldTypeDisplayName'), width: '6%' }, materialInfoProductionRemark: { title: app.localize('ProductionRemark'), width: '8%' }, materialInfoBundleCountDisplayName: { title: app.localize('BundleCountDisplayName'), width: '3%' }, materialInfoUnitDisplayName: { title: app.localize('UnitDisplayName'), width: '3%' }, materialInfoProcessCost: { title: app.localize('ProcessCost'), width: '6%' }, materialInfoProductRemark: { title: app.localize('ProductRemark'), width: '6%' }, materialInfoRemark: { title: app.localize('Remark'), width: '6%' }, count: { title: app.localize('申購(gòu)數(shù)量'), width: '6%' }, remark: { title: app.localize('申購(gòu)備注'), width: '6%' } } }, function (data) { data.childTable.jtable('load', { requisitionId: detailData.record.id } ); }); }); return $img; } }, no: { title: "申購(gòu)單號(hào)", width: '20%' }, creatorUserName: { title: "申購(gòu)人", width: '20%' }, creationTime: { title: "申購(gòu)時(shí)間", width: '10%', display: function (data) { return moment(data.record.creationTime).format('YYYY-MM-DD HH:mm:ss'); } }, sumCount: { title: "總數(shù)", width: '10%' }, status: { title: "狀態(tài)", width: '20%', display: function (data) { if (data.record.status === app.order.requisitionAuditStatus.audit) return '<span class="label label-info">' + app.localize('Autdit') + '</span>' else if (data.record.status === app.order.requisitionAuditStatus.auditPass) return '<span class="label label-success">' + app.localize('Pass') + '</span>' else if (data.record.status === app.order.requisitionAuditStatus.auditReject) return '<span class="label label-danger">' + app.localize('Reject') + '</span>' else if (data.record.status === app.order.requisitionAuditStatus.delete) return '<span class="label label-danger">' + app.localize('Abandon') + '</span>' else return '<span class="label label-danger">' + app.localize('Unknown') + '</span>' } } } }); }); })();
得到如下效果:
代碼釋疑:
(1) var _service = abp.services.app.requisition
; 這一句聲明當(dāng)前頁面需要使用哪個(gè)服務(wù)。
(2) _service.getRequisitionListAsync
這一句對(duì)應(yīng)的是服務(wù)調(diào)用的方法,你會(huì)發(fā)現(xiàn)在后臺(tái)方法名是GetRequisitionListAsync(),而在js里面卻變成了getRequisitionListAsync()
,我們暫且稱之為“潛規(guī)則”。
2、bootstrapTable在ABP項(xiàng)目里面的封裝
通過上述代碼你會(huì)發(fā)現(xiàn),ABP在application層里面定義的方法,最終會(huì)生成某一些js對(duì)應(yīng)的function,這里難點(diǎn)來了。我們找遍了bootstrapTable組件的api,都沒有通過某一個(gè)function去獲取數(shù)據(jù)的啊。這可如何是好?為這個(gè)問題,博主折騰了兩天。最開始博主想,function最終還不是要換成http請(qǐng)求的,我們只要拿到http請(qǐng)求的url,然后將function轉(zhuǎn)換為url不就行了么:
我們使用bootstrapTable組件初始化的時(shí)候聲明 {url:'/api/services/app/requisition/GetRequisitionListAsync'} 這樣不就行了么?呵呵,經(jīng)過測(cè)試,這樣確實(shí)能正確取到數(shù)據(jù)。但是不夠理想,因?yàn)檫@前面的前綴是ABP給我們生成的,是否會(huì)變化我們尚且不說,給每一個(gè)url加上這么一長(zhǎng)串著實(shí)看著很不爽,于是進(jìn)一步想,是否我們的bootstrapTable也可以使用function去初始化呢,組件沒有,難道我們就不能給他擴(kuò)展一個(gè)嗎?我們不用url獲取數(shù)據(jù),通過調(diào)用這個(gè)function取到數(shù)據(jù),然后將數(shù)據(jù)渲染到組件不就行了。思路有了,那么這里有兩個(gè)難題:一是如何將原來url的方式變成這里的調(diào)用function的方式呢?二是參數(shù)的封裝。經(jīng)過查看組件的源碼發(fā)現(xiàn),如果是服務(wù)端分頁,組件最終是進(jìn)入到initServer()這個(gè)方法去獲取數(shù)據(jù),然后渲染到頁面上面的,組件原始的initServer()方法如下:
BootstrapTable.prototype.initServer = function (silent, query) { var that = this, data = {}, params = { pageSize: this.options.pageSize === this.options.formatAllRows() ? this.options.totalRows : this.options.pageSize, pageNumber: this.options.pageNumber, searchText: this.searchText, sortName: this.options.sortName, sortOrder: this.options.sortOrder }, request; if (!this.options.url && !this.options.ajax) { return; } if (this.options.queryParamsType === 'limit') { params = { search: params.searchText, sort: params.sortName, order: params.sortOrder }; if (this.options.pagination) { params.limit = this.options.pageSize === this.options.formatAllRows() ? this.options.totalRows : this.options.pageSize; params.offset = this.options.pageSize === this.options.formatAllRows() ? : this.options.pageSize * (this.options.pageNumber - 1); } } if (!($.isEmptyObject(this.filterColumnsPartial))) { params['filter'] = JSON.stringify(this.filterColumnsPartial, null); } data = calculateObjectValue(this.options, this.options.queryParams, [params], data); $.extend(data, query || {}); // false to stop request if (data === false) { return; } if (!silent) { this.$tableLoading.show(); } request = $.extend({}, calculateObjectValue(null, this.options.ajaxOptions), { type: this.options.method, url: this.options.url, data: this.options.contentType === 'application/json' && this.options.method === 'post' ? JSON.stringify(data) : data, cache: this.options.cache, contentType: this.options.contentType, dataType: this.options.dataType, success: function (res) { res = calculateObjectValue(that.options, that.options.responseHandler, [res], res); that.load(res); that.trigger('load-success', res); }, error: function (res) { that.trigger('load-error', res.status, res); }, complete: function () { if (!silent) { that.$tableLoading.hide(); } } }); if (this.options.ajax) { calculateObjectValue(this, this.options.ajax, [request], null); } else { $.ajax(request); } };
代碼不難讀懂,解析參數(shù),整合參數(shù),得到參數(shù),發(fā)送ajax請(qǐng)求,在success事件里面將得到的數(shù)據(jù)渲染到界面。讀懂了這段代碼,我們?cè)賮矸庋bfunction就容易多了。
最終我們封裝的代碼如下:
(function ($) { 'use strict'; //debugger; //通過構(gòu)造函數(shù)獲取到bootstrapTable里面的初始化方法 var BootstrapTable = $.fn.bootstrapTable.Constructor, _initData = BootstrapTable.prototype.initData, _initPagination = BootstrapTable.prototype.initPagination, _initBody = BootstrapTable.prototype.initBody, _initServer = BootstrapTable.prototype.initServer, _initContainer = BootstrapTable.prototype.initContainer; //重寫 BootstrapTable.prototype.initData = function () { _initData.apply(this, Array.prototype.slice.apply(arguments)); }; BootstrapTable.prototype.initPagination = function () { _initPagination.apply(this, Array.prototype.slice.apply(arguments)); }; BootstrapTable.prototype.initBody = function (fixedScroll) { _initBody.apply(this, Array.prototype.slice.apply(arguments)); }; BootstrapTable.prototype.initServer = function (silent, query) { //構(gòu)造自定義參數(shù) for (var key in this.options.methodParams) { $.fn.bootstrapTable.defaults.methodParams[key] = this.options.methodParams[key]; } //如果傳了url,則走原來的邏輯 if (this.options.url) { _initServer.apply(this, Array.prototype.slice.apply(arguments)); return; } //如果定義了abpMethod,則走abpMethod的邏輯 if (!this.options.abpMethod) { return; } var that = this, data = {}, params = { pageSize: this.options.pageSize === this.options.formatAllRows() ? this.options.totalRows : this.options.pageSize, pageNumber: this.options.pageNumber, searchText: this.searchText, sortName: this.options.sortName, sortOrder: this.options.sortOrder }, request; //debugger; if (this.options.queryParamsType === 'limit') { params = { search: params.searchText, sort: params.sortName, order: params.sortOrder }; if (this.options.pagination) { params.limit = this.options.pageSize === this.options.formatAllRows() ? this.options.totalRows : this.options.pageSize; params.offset = this.options.pageSize === this.options.formatAllRows() ? 0 : this.options.pageSize * (this.options.pageNumber - 1); } } if (!($.isEmptyObject(this.filterColumnsPartial))) { params['filter'] = JSON.stringify(this.filterColumnsPartial, null); } data = $.fn.bootstrapTable.utils.calculateObjectValue(this.options, this.options.queryParams, [params], data); $.extend(data, query || {}); // false to stop request if (data === false) { return; } if (!silent) { this.$tableLoading.show(); } this.options.abpMethod(data).done(function (result) { result = $.fn.bootstrapTable.utils.calculateObjectValue(that.options, that.options.responseHandler, [result], result); that.load(result); that.trigger('load-success', result); }); request = $.extend({}, $.fn.bootstrapTable.utils.calculateObjectValue(null, this.options.ajaxOptions), { type: this.options.method, url: this.options.url, data: this.options.contentType === 'application/json' && this.options.method === 'post' ? JSON.stringify(data) : data, cache: this.options.cache, contentType: this.options.contentType, dataType: this.options.dataType, success: function (res) { debugger; res = $.fn.bootstrapTable.utils.calculateObjectValue(that.options, that.options.responseHandler, [res], res); that.load(res); that.trigger('load-success', res); }, error: function (res) { that.trigger('load-error', res.status, res); }, complete: function () { if (!silent) { that.$tableLoading.hide(); } } }); if (this.options.ajax) { $.fn.bootstrapTable.utils.calculateObjectValue(this, this.options.ajax, [request], null); } else { $.ajax(request); } } BootstrapTable.prototype.initContainer = function () { _initContainer.apply(this, Array.prototype.slice.apply(arguments)); }; abp.bootstrapTableDefaults = { striped: false, classes: 'table table-striped table-bordered table-advance table-hover', pagination: true, cache: false, sidePagination: 'server', uniqueId: 'id', showRefresh: false, search: false, method: 'post', //toolbar: '#toolbar', pageSize: 10, paginationPreText: '上一頁', paginationNextText: '下一頁', queryParams: function (param) { //$.fn.bootstrapTable.defaults.methodParams.propertyIsEnumerable() var abpParam = { Sorting: param.sort, filter: param.search, skipCount: param.offset, maxResultCount: param.limit }; for (var key in $.fn.bootstrapTable.defaults.methodParams) { abpParam[key] = $.fn.bootstrapTable.defaults.methodParams[key]; } return abpParam; }, responseHandler: function (res) { if (res.totalCount) return { total: res.totalCount, rows: res.items }; else return { total: res.result.totalCount, rows: res.result.items }; }, methodParams: {}, abpMethod: function () { } }; $.extend($.fn.bootstrapTable.defaults, abp.bootstrapTableDefaults); })(jQuery);
代碼釋疑:增加兩個(gè)參數(shù) methodParams: {},abpMethod: function () { } 來獲取abp的function和參數(shù),然后獲取數(shù)據(jù)的時(shí)候如果定義了abpMethod,則通過function獲取數(shù)據(jù),否則還是走原來的邏輯。
然后我們調(diào)用就簡(jiǎn)單了
//選取界面上要先數(shù)據(jù)的表格 var _$SendOrdersTable = $('#SendOrdersTable'); //獲取服務(wù)層方法 var _SendOrderService = abp.services.app.sendOrder; _$SendOrdersTable.bootstrapTable({ abpMethod: _SendOrderService.getSendOrderListAsync, detailView: true, onExpandRow: function (index, row, $detail) { var cur_table = $detail.html('<table></table>').find('table'); $(cur_table).bootstrapTable({ showRefresh: false, search: false, pagination: false, abpMethod: _SendOrderService.getSendOrderDetailListAsync, methodParams: { SendOrderId: row.id }, columns: [ { field: 'materialClassName', title: app.localize('MaterialClassName'), width: '8%' }, { field: 'typeNo', title: app.localize('TypeNo'), width: '8%' } ] }); }, columns: [{ field: 'no', title: app.localize('SendOrderNO'), align: 'center' }, { field: 'supplierName', title: app.localize('SupplierName'), align: 'center' }, { title: app.localize('SendOrderTime'), align: 'center', field: 'createdDate', formatter: function (data) { return moment(data).format('YYYY-MM-DD HH:mm:ss'); } }, { field: 'status', align: 'center', title: app.localize('SendOrderStatus'), formatter: function (data) { var value = ""; if (data == 1) { value = '<span class="label label-info">' + app.localize('Autdit') + '</span>'; } else if (data == 2) { value = '<span class="label label-success">' + app.localize('Pass') + '</span>'; } else if (data == 3) { value = '<span class="label label-default">' + app.localize('Reject') + '</span>'; } else value = '<span class="label label-default">' + app.localize('Abandon') + '</span>'; return value; } }, { field: 'createName', align: 'center', title: app.localize('SendOrderCreator'), }, { field: 'sumCount', align: 'center', title: app.localize('SendOrderTotalCount'), }, ] });
得到如下效果
上述內(nèi)容就是如何在ABP框架中使用BootstrapTable組件,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司行業(yè)資訊頻道。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
文章標(biāo)題:如何在ABP框架中使用BootstrapTable組件-創(chuàng)新互聯(lián)
分享路徑:http://jinyejixie.com/article32/djeosc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、手機(jī)網(wǎng)站建設(shè)、微信小程序、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容