<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        在ABP框架中使用BootstrapTable組件的方法

        來源:懂視網 責編:小采 時間:2020-11-27 22:33:28
        文檔

        在ABP框架中使用BootstrapTable組件的方法

        在ABP框架中使用BootstrapTable組件的方法:一、關于ABP ABP是ASP.NET Boilerplate Project (ASP.NET樣板項目)的簡稱,它是一個成熟的開源框架,基于DDD+Repository模式,自帶Zero權限和認證模塊,避免了從零開始搭建框架的煩惱。關于ABP的框架優勢就此打住,因為這樣說下去要說三天三夜,脫離文
        推薦度:
        導讀在ABP框架中使用BootstrapTable組件的方法:一、關于ABP ABP是ASP.NET Boilerplate Project (ASP.NET樣板項目)的簡稱,它是一個成熟的開源框架,基于DDD+Repository模式,自帶Zero權限和認證模塊,避免了從零開始搭建框架的煩惱。關于ABP的框架優勢就此打住,因為這樣說下去要說三天三夜,脫離文

        一、關于ABP

        ABP是“ASP.NET Boilerplate Project (ASP.NET樣板項目)”的簡稱,它是一個成熟的開源框架,基于DDD+Repository模式,自帶Zero權限和認證模塊,避免了從零開始搭建框架的煩惱。關于ABP的框架優勢就此打住,因為這樣說下去要說三天三夜,脫離文本主題。

        關于ABP的入門,博主不想說太多,園子里面tkb至簡和陽光銘睿有很多入門級的文章,有興趣的可以了解下,還是給出它的官網和開源地址。

        ABP官方網站:http://www.aspnetboilerplate.com

        ABP開源項目:https://github.com/aspnetboilerplate

        PS:如果你不愿意去看它的源碼,可以直接查看ABP官網上面的演示地址:https://aspnetzero.com/?ref=abptmplpage

        點擊CREATE MY DEMO按鈕,系統會自動為你生成演示地址

        進入對應的Demo URL

        使用演示的用戶名和密碼登陸進去

        可以看到Zero模塊的實現效果。

        二、jTable在ABP中的運用

        如果你下載ABP的源碼,并且選擇的是混合開發模式(ABP提供了兩種開發模式,一種是基于MVVM的Angular.js的模式;另一種就是MVC+jQuery的混合開發模式),如下圖:

        當你Down下來源碼之后你就會發現,ABP的源碼里面的UI部分的表格都是使用jTable去實現的。為什么會用jTable?原因很簡單,jTable是ABP的作者kalkan寫的一款開源插件,自己寫的肯定用自己的東西嘍。下面jTable的效果來一發。

        來一個jtable的父子表:

        如果是不帶父子表的簡單表格,其實jTable的效果其實還行,可是加上一些復雜的功能之后,那一片片藍色的區域不忍直視,并且jTable的api還有待完善,很多需要的功能都需要自己去實現,于是就接到了將所有的表格組件換成BootstrapTable的需求,才有了今天的主題:在ABP中封裝BootstrapTable。

        三、Bootstrap Table在ABP中的封裝

        接到需求,博主各種百度、各種谷歌,都找不到Bootstrap Table組件在ABP中的封裝,有的只是在ABP的項目里面簡單的用傳統的方式去初始化組件,這并不是博主想要的。說到這里不得不說一下,如果你使用ABP開發的過程中遇到一些難題,你會發現很難從百度里面搜索到相關答案,谷歌里面有時能找到,但大部分都是英文社區,所以如果你英文較弱,在查找資料上面會很吃虧,有時一個簡單的配置問題需要折騰很久。

        1、jTable在ABP項目里面的初始化

        首先來看看jTable在一般的ABP項目里面是如何初始化的。比如我們在Application里面有一個如下的接口和實現

         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
         );
         }
         }

        然后我們前端有一個頁面的列表數據從這個接口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="https://www.gxlcms.com/Common/Images/list_metro.png" title="申購明細" />');
         $img.click(function () {
         _$dataListTable.jtable('openChildTable',
         $img.closest('tr'),
         {
         title: "申購明細",
         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('申購數量'),
         width: '6%'
         },
         remark: {
         title: app.localize('申購備注'),
         width: '6%'
         }
         }
         }, function (data) {
         data.childTable.jtable('load',
         { requisitionId: detailData.record.id }
         );
         });
         });
         return $img;
         }
         },
         no: {
         title: "申購單號",
         width: '20%'
         },
         creatorUserName: {
         title: "申購人",
         width: '20%'
         },
         creationTime: {
         title: "申購時間",
         width: '10%',
         display: function (data) {
         return moment(data.record.creationTime).format('YYYY-MM-DD HH:mm:ss');
         }
         },
         sumCount: {
         title: "總數",
         width: '10%'
         },
         status: {
         title: "狀態",
         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; 這一句聲明當前頁面需要使用哪個服務。

        (2)  _service.getRequisitionListAsync 這一句對應的是服務調用的方法,你會發現在后臺方法名是GetRequisitionListAsync(),而在js里面卻變成了getRequisitionListAsync(),我們暫且稱之為“潛規則”。

        2、bootstrapTable在ABP項目里面的封裝

        通過上述代碼你會發現,ABP在application層里面定義的方法,最終會生成某一些js對應的function,這里難點來了。我們找遍了bootstrapTable組件的api,都沒有通過某一個function去獲取數據的啊。這可如何是好?為這個問題,博主折騰了兩天。最開始博主想,function最終還不是要換成http請求的,我們只要拿到http請求的url,然后將function轉換為url不就行了么:

        我們使用bootstrapTable組件初始化的時候聲明  {url:'/api/services/app/requisition/GetRequisitionListAsync'}  這樣不就行了么?呵呵,經過測試,這樣確實能正確取到數據。但是不夠理想,因為這前面的前綴是ABP給我們生成的,是否會變化我們尚且不說,給每一個url加上這么一長串著實看著很不爽,于是進一步想,是否我們的bootstrapTable也可以使用function去初始化呢,組件沒有,難道我們就不能給他擴展一個嗎?我們不用url獲取數據,通過調用這個function取到數據,然后將數據渲染到組件不就行了。思路有了,那么這里有兩個難題:一是如何將原來url的方式變成這里的調用function的方式呢?二是參數的封裝。經過查看組件的源碼發現,如果是服務端分頁,組件最終是進入到initServer()這個方法去獲取數據,然后渲染到頁面上面的,組件原始的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);
         }
         };

        代碼不難讀懂,解析參數,整合參數,得到參數,發送ajax請求,在success事件里面將得到的數據渲染到界面。讀懂了這段代碼,我們再來封裝function就容易多了。

        最終我們封裝的代碼如下:

        (function ($) {
         'use strict';
         //debugger;
         //通過構造函數獲取到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) {
         //構造自定義參數
         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);

        代碼釋疑:增加兩個參數 methodParams: {},abpMethod: function () { } 來獲取abp的function和參數,然后獲取數據的時候如果定義了abpMethod,則通過function獲取數據,否則還是走原來的邏輯。

        然后我們調用就簡單了

        //選取界面上要先數據的表格
         var _$SendOrdersTable = $('#SendOrdersTable');
         //獲取服務層方法
         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'),
         },
         ]
         });

        得到如下效果

        總結

        以上所述是小編給大家介紹的在ABP框架中使用BootstrapTable組件的方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        在ABP框架中使用BootstrapTable組件的方法

        在ABP框架中使用BootstrapTable組件的方法:一、關于ABP ABP是ASP.NET Boilerplate Project (ASP.NET樣板項目)的簡稱,它是一個成熟的開源框架,基于DDD+Repository模式,自帶Zero權限和認證模塊,避免了從零開始搭建框架的煩惱。關于ABP的框架優勢就此打住,因為這樣說下去要說三天三夜,脫離文
        推薦度:
        標簽: 組件 table 框架
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 野花香高清视频在线观看免费| 在线v片免费观看视频| 免费无码一区二区三区蜜桃大 | 91热久久免费精品99| 亚洲色无码一区二区三区| 国产亚洲福利一区二区免费看| 91成人免费福利网站在线| 亚洲国产精品自在拍在线播放| 亚洲午夜视频在线观看| 国产精品亚洲专区在线观看| 99久久综合精品免费| 亚洲综合久久成人69| j8又粗又长又硬又爽免费视频| 7x7x7x免费在线观看| 亚洲精品午夜久久久伊人| 可以免费看的卡一卡二| 亚洲AV色吊丝无码| 精品少妇人妻AV免费久久洗澡| 337p日本欧洲亚洲大胆精品555588| 亚洲国产综合AV在线观看| 精品熟女少妇av免费久久| 亚洲伊人久久大香线焦| 日韩视频免费在线| a在线视频免费观看在线视频三区| 久久午夜免费视频| 亚洲精品欧美综合四区| 亚洲精品第一国产综合境外资源| 亚洲av无码片区一区二区三区| 国产精品免费观看视频| 久久精品亚洲一区二区| 国产精品一区二区三区免费| 亚洲精品成人片在线播放 | 免费无码H肉动漫在线观看麻豆| 毛片免费观看的视频在线| 美国免费高清一级毛片| 久久久亚洲精品蜜桃臀| 亚洲w码欧洲s码免费| 国产精品亚洲专一区二区三区| 在线免费观看污网站| 亚洲精品国产成人中文| 永久免费毛片手机版在线看|