1. 程式人生 > >ABP入門系列(14)——應用BootstrapTable表格外掛

ABP入門系列(14)——應用BootstrapTable表格外掛

1. 引言

之前的文章ABP入門系列(7)——分頁實現講解了如何進行分頁展示,但其分頁展示僅適用於前臺web分頁,在後臺管理系統中並不適用。後臺管理系統中的資料展示一般都是使用一些表格外掛來完成的。這一節我們就使用BootstrapTable進行舉例說明。

最終效果圖

2. BootstrapTable

基於 Bootstrap 的 jQuery 表格外掛,通過簡單的設定,就可以擁有強大的單選、多選、排序、分頁,以及編輯、匯出、過濾(擴充套件)等等的功能。

Bootstrap table是一個開源的輕量級功能非常豐富的前端表格外掛。從命名來看就知道該表格樣式由Bootstrap接手了,我們就不必糾結於樣式的調整了。想對其有詳細瞭解,可參考

官方文件

廢話不多說,下面我們就直接上手演練。

3. 實操演練

因為使用BootstrapTable進行分頁,主要的難點在外掛的配置上,所以這一次我們直接對主要程式碼進行講解,原始碼請自行前往Github上檢視。

3.1. 新增BackendTasksController控制器

控制器中主要定義了列表、建立、編輯相關Action。其中最重要的方法是進行資料繫結的Aciton GetAllTasks,程式碼如下:

[DontWrapResult] 
public JsonResult GetAllTasks(int limit, int offset, string sortfiled, string sortway, string search, string status) {
    var sort = !string.IsNullOrEmpty(sortfiled) ? string.Format("{0} {1}", sortfiled, sortway) : "";
    TaskState currentState;
    if (!string.IsNullOrEmpty(status)) Enum.TryParse(status, true, out currentState);

    var filter = new GetTasksInput {
        SkipCount = offset,
        MaxResultCount = limit,
        Sorting = sort,
        Filter = search
    };

    if (!string.IsNullOrEmpty(status)) if (Enum.TryParse(status, true, out currentState)) filter.State = currentState;

    var pagedTasks = _taskAppService.GetPagedTasks(filter);

    return Json(new {
        total = pagedTasks.TotalCount,
        rows = pagedTasks.Items
    },
    JsonRequestBehavior.AllowGet);
}

下面來一一講解下引數:

  • limit:分頁引數,指定每頁最多顯示多少行;
  • offset:分頁引數,指定偏移量;
  • sortField:排序引數,排序欄位;
  • sortWay:排序引數,排序方式(升序or降序);
  • search:過濾引數,指定過濾的任務名稱;
  • status:過濾引數,指定過濾的任務狀態

這裡面要注意的是引數的命名和順序必須和前端傳參保持一致
細心的你可能發現Action使用了[DontWrapResult]特性進行修飾,這樣返回的json結果就不會被Abp提供的AbpJsonResult包裹,瞭解AbpJsonResult可參考ABP入門系列(8)——Json格式化

3.2. 新增List.cshtml進行列表展示

List.cshtml中主要的程式碼為:

@using Abp.Web.Mvc.Extensions
@{
    ViewBag.Title = L("BackendTaskList");
    ViewBag.ActiveMenu = "BackendTaskList"; //Matches with the menu name in SimpleTaskAppNavigationProvider to highlight the menu item
}

<!-- 載入bootstrap-tablel的樣式 -->
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.0/bootstrap-table.min.css">
@section scripts{
    @Html.IncludeScript("~/Views/backendtasks/list.js");
    <!-- 載入bootstrap-tablel的script指令碼 -->
    <script src="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.0/bootstrap-table.min.js"></script>

    <!-- Latest compiled and minified Locales -->
    <script src="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.0/locale/bootstrap-table-zh-CN.min.js"></script>
}

<div class="row">
    <div class="panel-body">
        <!-- 過濾框 -->
        <div class="panel panel-default">
            <div class="panel-heading">查詢條件</div>
            <div class="panel-body">
                <form id="formSearch" class="form-horizontal">
                    <div class="form-group" style="margin-top: 15px">
                        <label class="control-label col-sm-1" for="txt-filter">任務名稱</label>
                        <div class="col-sm-3">
                            <input type="text" class="form-control" id="txt-filter">
                        </div>

                        <label class="control-label col-sm-1" for="txt-search-status">狀態</label>
                        <div class="col-sm-3">
                            @Html.DropDownList("TaskStateDropdownList", null, new {id = "txt-search-status", @class = "form-control "})
                        </div>
                        <div class="col-sm-4" style="text-align: left;">
                            <button type="button" style="margin-left: 50px" id="btn-query" class="btn btn-primary">查詢</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <!-- bootstrap-tablel指定的工具欄 -->
    <div id="toolbar" class="btn-group">
        <button id="btn-add" type="button" class="btn btn-primary">
            <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增
        </button>
        <button id="btn-edit" type="button" class="btn btn-success">
            <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>修改
        </button>
        <button id="btn-delete" type="button" class="btn btn-danger">
            <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>刪除
        </button>
    </div>

    <!--bootstrap-table表體-->
    <table id="tb-tasks"></table>
</div>

<!--通過初始載入頁面的時候提前將建立任務模態框載入進來-->
@Html.Partial("_CreateTask")

<!--編輯任務模態框通過ajax動態填充到此div中-->
<div id="edit">
</div>

由於是demo性質,我直接使用的CDN來載入bootstrap table相關的css,js。
其中首先定義了過濾框,然後定義了bootstrap table專用的工具欄,其會在後續bootstrap table初始化指定。
接著使用<table id="tb-tasks"></table>來定義bootstrap-table表體。

3.3. 新增list.js初始化bootstrap table

初始化就是為bootstrap table指定資料來源進行資料繫結、列名定義、排序欄位、分頁,事件繫結等。
我們新建一個list.js來進行初始化:

$(function() {

    //1.初始化Table
    var oTable = new TableInit();
    oTable.Init();

    //2.初始化Button的點選事件
    var oButtonInit = new ButtonInit();
    oButtonInit.Init();

});

var taskService = abp.services.app.task;
var $table = $('#tb-tasks');
var TableInit = function() {
    var oTableInit = new Object();
    //初始化Table
    oTableInit.Init = function() {
        $table.bootstrapTable({
            url: '/BackendTasks/GetAllTasks', //請求後臺的URL(*)
            method: 'get', //請求方式(*)
            toolbar: '#toolbar', //工具按鈕用哪個容器
            striped: true, //是否顯示行間隔色
            cache: false, //是否使用快取,預設為true,所以一般情況下需要設定一下這個屬性(*)
            pagination: true, //是否顯示分頁(*)
            sortable: true, //是否啟用排序
            sortOrder: "asc", //排序方式
            queryParams: oTableInit.queryParams, //傳遞引數(*)
            sidePagination: "server", //分頁方式:client客戶端分頁,server服務端分頁(*)
            pageNumber: 1, //初始化載入第一頁,預設第一頁
            pageSize: 5, //每頁的記錄行數(*)
            pageList: [10, 25, 50, 100], //可供選擇的每頁的行數(*)
            search: false, //是否顯示錶格搜尋,此搜尋是客戶端搜尋,不會進服務端,所以,個人感覺意義不大
            strictSearch: true,
            showColumns: true, //是否顯示所有的列
            showRefresh: true, //是否顯示重新整理按鈕
            minimumCountColumns: 2, //最少允許的列數
            clickToSelect: true, //是否啟用點選選中行
            height: 500, //行高,如果沒有設定height屬性,表格自動根據記錄條數覺得表格高度
            uniqueId: "Id", //每一行的唯一標識,一般為主鍵列
            showToggle: true, //是否顯示詳細檢視和列表檢視的切換按鈕
            cardView: false, //是否顯示詳細檢視
            detailView: false, //是否顯示父子表
            columns: [
                {
                    radio: true
                }, {
                    field: 'Title',
                    title: '任務名稱',
                    sortable: true
                }, {
                    field: 'Description',
                    title: '任務描述'
                }, {
                    field: 'AssignedPersonName',
                    title: '任務分配'
                }, {
                    field: 'State',
                    title: '任務狀態',
                    formatter: showState
                }, {
                    field: 'CreationTime',
                    title: '建立日期',
                    formatter: showDate
                }, {
                    field: 'operate',
                    title: '操作',
                    align: 'center',
                    valign: 'middle',
                    clickToSelect: false,
                    formatter: operateFormatter,
                    events: operateEvents
                }
            ]
        });
    };

這段JS中bootstrap table初始化配置的引數說明已經在程式碼中進行了註釋。
下面對幾個重要的引數進行講解:

3.3.1. queryParams查詢引數

初始化的時候我們指定了查詢引數為:
queryParams: oTableInit.queryParams, //傳遞引數(*)
其中queryParams函式定義如下:

//指定bootstrap-table查詢引數
oTableInit.queryParams = function(params) {
    var temp = { //這裡的鍵的名字和控制器的變數名必須一直,這邊改動,控制器也需要改成一樣的
        limit: params.limit,
        //頁面大小
        offset: params.offset,
        //頁碼
        sortfiled: params.sort,
        //排序欄位
        sortway: params.order,
        //升序降序
        search: $("#txt-filter").val(),
        //自定義傳參-任務名稱
        status: $("#txt-search-status").val() //自定義傳參-任務狀態
    };
    return temp;
};

和控制器中的Action的函式命名進行比較public JsonResult GetAllTasks(int limit, int offset, string sortfiled, string sortway, string search, string status),其中引數命名的大小寫以及順序與js中定義的查詢引數保持一致,這也是必須要注意的一點。

3.3.2. 資料繫結

資料繫結包括以下三個部分:

  • url:就是用來指定請求後臺的URL;
  • uniqueid:用來繫結每一行的唯一標識列,一般為主鍵列
  • columns:用來繫結每一列要顯示的資料。

針對columns引數,其中field必須與你請求返回的json資料的key大小寫保持一致;
title就是顯示的列名;
align指定列的水平對其方式;
valign指定列的垂直對齊方式;
formatter用來指定列如何進行格式化輸出,如操作列中指定formatter: operateFormatter,用來顯示統一格式的操作組;

//指定操作組
    function operateFormatter(value, row, index) {
        return [
            '<a class="like" href="javascript:void(0)" title="Like">',
            '<i class="glyphicon glyphicon-heart"></i>',
            '</a>',
            ' <a class="edit" href="javascript:void(0)" title="Edit">',
            '<i class="glyphicon glyphicon-edit"></i>',
            '</a>',
            ' <a class="remove" href="javascript:void(0)" title="Remove">',
            '<i class="glyphicon glyphicon-remove"></i>',
            '</a>'
        ].join('');
    }

events用來指定列的事件,比如操作列中指定events: operateEvents來指定每個操作對應的事件處理:

    //指定table表體操作事件
    window.operateEvents = {
        'click .like': function(e, value, row, index) {
            alert('You click like icon, row: ' + JSON.stringify(row));
            console.log(value, row, index);
        },
        'click .edit': function(e, value, row, index) {
            editTask(row.Id);
        },
        'click .remove': function(e, value, row, index) {
            deleteTask(row.Id);
        }
    };

3.3.3. 工具欄事件繫結

工具欄是我們在List.cshtml定義的新增、編輯、刪除三個按鈕,表格初始化時,直接為toolbar引數指定工具欄對應的id即可,如本例toolba: '#toolbar'。那工具欄按鈕的事件在哪繫結呢?直接上程式碼吧:

//bootstrap-table工具欄按鈕事件初始化
var ButtonInit = function() {
    var oInit = new Object();
    var postdata = {};

    oInit.Init = function() {
        //初始化頁面上面的按鈕事件
        $("#btn-add")
            .click(function() {
                $("#add").modal("show");
            });

        $("#btn-edit")
            .click(function() {
                var selectedRaido = $table.bootstrapTable('getSelections');
                if (selectedRaido.length === 0) {
                    abp.notify.warn("請先選擇要編輯的行!");
                } else {
                    editTask(selectedRaido[0].Id);
                }
            });

        $("#btn-delete")
            .click(function() {
                var selectedRaido = $table.bootstrapTable('getSelections');
                if (selectedRaido.length === 0) {
                    abp.notify.warn("請先選擇要刪除的行!");
                } else {
                    deleteTask(selectedRaido[0].Id);
                }
            });

        $("#btn-query")
            .click(function() {
                $table.bootstrapTable('refresh');
            });
    };
    return oInit;
};

該方法會在頁面載入初被呼叫:
var oButtonInit = new ButtonInit(); oButtonInit.Init();

另外函式中使用了bootstrap table預置的2個比較實用的函式:

  • $table.bootstrapTable('getSelections'):獲取表格選擇項
  • $table.bootstrapTable('refresh'):重新整理表格

4. 總結

本文主要講解了如何使用bootstrap table進行後臺分頁的一般用法,講解了bootstrap table引數的配置和幾個注意事項。其中有很多功能並未講到,具體請自行查詢文件。
前端的外掛用法,看似複雜,實則動手操作也還ok,所以重在動手實踐。

相關推薦

ABP入門系列14——應用BootstrapTable表格外掛

1. 引言 之前的文章ABP入門系列(7)——分頁實現講解了如何進行分頁展示,但其分頁展示僅適用於前臺web分頁,在後臺管理系統中並不適用。後臺管理系統中的資料展示一般都是使用一些表格外掛來完成的。這一節我們就使用BootstrapTable進行舉例說明。 2. BootstrapTable 基於 B

ABP入門系列4——建立應用服務

一、解釋下應用服務層 應用服務用於將領域(業務)邏輯暴露給展現層。展現層通過傳入DTO(資料傳輸物件)引數來呼叫應用服務,而應用服務通過領域物件來執行相應的業務邏輯並且將DTO返回給展現層。因此,展現層和領域層將被完全隔離開來。 以下幾點,在建立應用服務時需要注意: 在ABP中,一個應用服務需要實現IAp

ABP入門系列12——如何升級Abp並除錯原始碼

1. 升級Abp 本系列教程是基於Abp V1.0版本,現在Abp版本已經升級至V1.4.2(截至至文章釋出時間),其中新增了New Feature,並對Abp做了相應的Enhancements,以及Bug fixs。現在我們就把它升級至最新版本,那如何升級呢? 下面就請按我的步驟來將Abp由V1.0升級

ABP入門系列16——通過webapi與系統進行互動

1. 引言 上一節我們講解了如何建立微信公眾號模組,這一節我們就繼續跟進,來講一講公眾號模組如何與系統進行互動。 微信公眾號模組作為一個獨立的web模組部署,要想與現有的【任務清單】進行互動,我們要想明白以下幾個問題: 如何進行互動? ABP模板專案中預設建立了webapi專案,其動態webapi技術允

ABP入門系列6——定義導航選單

完成了增刪改查以及頁面展示,這一節我們來為任務清單新增【導航選單】。 在以往的專案中,大家可能會手動在layout頁面中新增一個a標籤來新增導航選單,這也是一種方式,但是如果要針對不同使用者不同許可權決定是否顯示某個選單,那麼直接在layout頁面中去控制就不方便了。 不過,ABP已經為大家考慮了這一點,集

ABP入門系列8——Json格式化

講完了分頁功能,這一節我們先不急著實現新的功能。來簡要介紹下Abp中Json的用法。為什麼要在這一節講呢?當然是做鋪墊啊,後面的系列文章會經常和Json這個東西打交道。 一、Json是幹什麼的 JSON(JavaScript Object Notation) 是一種輕量級的資料交換格式。 易於人閱讀和編寫

ABP入門系列19——使用領域事件

1.引言 最近剛學習了下DDD中領域事件的理論知識,總的來說領域事件主要有兩個作用,一是解耦,二是使用領域事件進行事務的拆分,通過引入事件儲存,來實現資料的最終一致性。若想了解DDD中領域事件的概念,可參考DDD理論學習系列(9)-- 領域事件。 Abp中使用事件匯流排來實現領域事件,而關於事件匯流排的

ABP入門系列9——許可權管理

完成了簡單的增刪改查和分頁功能,是不是覺得少了點什麼? 是的,少了許可權管理。既然涉及到了許可權,那我們就細化下任務清單的功能點: 登入的使用者才能檢視任務清單 使用者可以無限建立任務並分配給自己,但只能對自己建立的任務進行查詢、修改 管理員可以建立任務並分配給他人 管理員具有刪除任務的許可權 從以上

ABP入門系列5——展現層實現增刪改查

這一章節將通過完善Controller、View、ViewModel,來實現展現層的增刪改查。最終實現效果如下圖: 一、定義Controller ABP對ASP.NET MVC Controllers進行了整合,通過引入Abp.Web.Mvc名稱空間,建立Controller繼承自AbpControlle

ABP入門系列18—— 使用領域服務

1.引言 自上次更新有一個多月了,發現越往下寫,越不知如何去寫。特別是當遇到DDD中一些概念術語的時候,尤其迷惑。如果只是簡單的去介紹如何去使用ABP,我只需參照官方文件,實現到任務清單Demo中去就可以了,不勞神不費力。但是,這樣就等於一知半解。 知之為知之,不知為不知,是知也。知其然知其所以然,方能舉

ABP入門系列2——領域層建立實體

這一節我們主要和領域層打交道。首先我們要對ABP的體系結構以及從模板建立的解決方案進行一一對應。網上有程式碼生成器去簡化我們這一步的任務,但是不建議初學者去使用。 一、首先來看看ABP體系結構 領域層就是業務層,是一個專案的核心,所有業務規則都應該在領域層實現。 實體(Entity): 實體代表業務領域的

ABP入門系列11——編寫單元測試

1. 前言 In computer programming, unit testing is a software testing method by which individual units of source code, sets of one or more computer program

ABP入門系列15——建立微信公眾號模組

1. 引言 現在的網際網路已不在僅僅侷限於網頁應用,IOS、Android、平板、智慧家居等平臺正如火如荼的迅速發展,移動應用的需求也空前旺盛。所有的網際網路公司都不想錯過這一次移動浪潮,佈局移動市場分一份移動紅利。 的確,智慧手機作為我們日常生活已必不可少的一部分,通過手機app能夠獲得更好的體驗,比如

ABP入門系列3——領域層定義倉儲並實現

一、先來介紹下倉儲 倉儲(Repository): 倉儲用來操作資料庫進行資料存取。倉儲介面在領域層定義,而倉儲的實現類應該寫在基礎設施層。 在ABP中,倉儲類要實現IRepository介面,介面定義了常用的增刪改查以及聚合方法,其中包括同步及非同步方法。主要包括以下方法: ABP針對不同的ORM框架對

ABP入門系列1——通過模板建立MAP版本專案

一、從官網建立模板專案 依次按下圖選擇: 輸入驗證碼開始下載 下載提示: 二、啟動專案 使用VS2015開啟專案,還原Nuget包: 設定以Web結尾的專案,設定為啟動專案: 開啟Web.config,修改連線字串。(因為我本地裝的sqlserver是例項是.sqlexpress,所以需要

ABP入門系列13——Redis快取用起來

1. 引言 建立任務時我們需要指定分配給誰,Demo中我們使用一個下拉列表用來顯示當前系統的所有使用者,以供使用者選擇。我們每建立一個任務時都要去資料庫取一次使用者列表,然後繫結到使用者下拉列表顯示。如果就單單對一個demo來說,這樣實現也無可厚非,但是在正式專案中,顯然是不合理的,浪費程式效能,有待優化

ABP入門系列7——分頁實現

完成了任務清單的增刪改查,咱們來講一講必不可少的的分頁功能。 首先很慶幸ABP已經幫我們封裝了分頁實現,實在是貼心啊。 來來來,這一節咱們就來捋一捋如何使用ABP的進行分頁吧。 一、分頁請求DTO定義 資料傳輸物件(Data Transfer Objects)用於應用層和展現層的資料傳輸。 展現層傳入資料

ABP入門系列17——使用ABP整合的郵件系統傳送郵件

ABP中對郵件的封裝主要整合在Abp.Net.Mail和Abp.Net.Mail.Smtp名稱空間下,相應原始碼在此。 #一、Abp整合的郵件模組是如何實現的 分析可以看出主要由以下幾個核心類組成: EmailSettingNames:靜態常量類,主要定義了傳送郵件需要的相關引數:Port、Host、Us

Android GIS開發系列-- 入門14FeatureLayer之範圍查詢

sso 偏差 .get http pri tex des else uil Android GIS開發系列-- 入門季(5),這篇文章中,我們知道如何去查找要素。現在有一個需求,查找某點5000米範圍的要素,那如何來做呢?首先我們需要在地圖上畫個5000米半徑的圓,然後根據

Golang 入門系列十三用Beego開發web應用

接著之前的內容,前面已經講過很多Golang的基礎語法,mysql的使用,redis的使用,也講了orm框架,如何建立一個webapi 服務等等,感興趣的可以看看以前的文章,https://www.cnblogs.com/zhangweizhong/category/1275863.html, 今天要來說一