5

循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序...

 3 years ago
source link: https://www.cnblogs.com/wuhuacong/p/14214889.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在很多列表展示数据的场合中,大多数都会需要一个排序的处理,以方便快速查找排序所需的数据,本篇随笔介绍如何结合ABP后端和Vue+Element前端结合的分页排序处理过程。

1、Vue+Element前端的排序代码

我们首先参考一下Element界面组件的排序说明。如下效果是Element表格组件的排序效果。

在列中设置sortable属性即可实现以该列为基准的排序,接受一个Boolean,默认为false。可以通过 Table 的default-sort属性设置默认的排序列和排序顺序。可以使用sort-method或者sort-by使用自定义的排序规则。如果需要后端排序,需将sortable设置为custom,同时在 Table 上监听sort-change事件,在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。在本例中,我们还使用了formatter属性,它用于格式化指定列的值,接受一个Function,会传入两个参数:rowcolumn,可以根据自己的需求进行处理。

根据上面说明,我们这里采取的是后端排序,将sortable设置为custom。如下案例代码所示。

    <!--表格列表信息 -->
    <el-table
      v-loading="listLoading"
      :data="list"
      border
      fit
      stripe
      highlight-current-row
      :header-cell-style="{background:'#eef1f6',color:'#606266'}"
      @selection-change="selectionChange"
      @row-dblclick="rowDbclick"
    @sort-change="sortChange"
    >
      <el-table-column type="selection" width="40" />
      <el-table-column align="center" sortable="custom" prop="name" label="姓名">
        <template slot-scope="scope">
          {{ scope.row.name }}
        </template>
      </el-table-column>
      <el-table-column align="center" sortable="custom" prop="age" label="年龄">
        <template slot-scope="scope">
          {{ scope.row.age }} 岁
        </template>
      </el-table-column>
      <!--日期字段信息,显示完整时间格式:formatter="timeFormat",否则使用:formatter="dateFormat" -->
      <el-table-column align="center" label="创建时间" sortable="custom" width="160" prop="creationTime" :formatter="timeFormat" />

以上是界面端的HTML代码,那么前端JS的处理逻辑也需要相应处理下,上面代码中 @sort-change="sortChange" 定义了排序变化的触发事件处理。

  methods: {
    sortChange({ column, prop, order }) {
      var direction = (order === 'ascending') ? ' ASC' : ' DESC'
      this.sorting = !this.isEmpty(prop) ? (prop + direction) : null
      this.getlist()
    },

以上代码主要逻辑是构建一个排序字符串,如:字段 ASC 或 字段 DESC的字符串,以供ABP后端的排序处理即可,这个主要是根据ABP框架排序特点进行提交的。

我们通过getlist的方法提交对应的查询条件和排序字符串,让后端再次获取数据给我们前端处理。

    getlist() { // 列表数据获取
      var param = { // 构造常规的分页查询条件
        // 分页条件
        SkipCount: (this.pageinfo.pageindex - 1) * this.pageinfo.pagesize,
        MaxResultCount: this.pageinfo.pagesize,
        Sorting: this.sorting,

      // 查询过滤条件
        Name: this.searchForm.name,
        AgeStart: this.searchForm.ageStart
      };
      // 使用日期范围选择控件,在查询对象增加开始日期CreationTimeStart、结束日期CreationTimeEnd
      this.addDateRange(param, this.searchForm.creationTime)

      // 获取列表,绑定到模型上,并修改分页数量
      this.listLoading = true
      customer.GetAll(param).then(data => {
        this.list = data.result.items
        this.pageinfo.total = data.result.totalCount
        this.listLoading = false
      })
    },

那么剩下的时候,就是后端如何处理数据的问题了。

2、 ABP后端分页排序的处理

我们查看ABP的应用服务层的接口基类可以看到,对应的获取所有记录GetAll方法的定义如下所示。

        public virtual async Task<PagedResultDto<TEntityDto>> GetAllAsync(TGetAllInput input)
        {
            CheckGetAllPermission();                 //检查权限

            var query = CreateFilteredQuery(input);  //构建查询条件

            var totalCount = await AsyncQueryableExecuter.CountAsync(query);  //获取记录总数

            query = ApplySorting(query, input);  //排序
            query = ApplyPaging(query, input);   //分页

            var entities = await AsyncQueryableExecuter.ToListAsync(query);  //返回实体记录

            return new PagedResultDto<TEntityDto>(  //构建分页展示数据
                totalCount,
                entities.Select(MapToEntityDto).ToList()  //实体转换DTO
            );
        }

一般情况下,这些逻辑我们一般不会变化,我们只需要进行一定的重写构建查询条件,以及排序规则即可。

例如重写条件查询获取查询对象的处理如下。

 详细代码如下所示:

        /// <summary>
        /// 自定义条件处理
        /// </summary>
        /// <param name="input">查询条件Dto</param>
        /// <returns></returns>
        protected override IQueryable<Customer> CreateFilteredQuery(CustomerPagedDto input)
        {
            return base.CreateFilteredQuery(input)
                .WhereIf(!input.ExcludeId.IsNullOrWhiteSpace(), t=>t.Id != input.ExcludeId) //不包含排除ID
                .WhereIf(!input.Name.IsNullOrWhiteSpace(), t => t.Name.Contains(input.Name)) //如需要精确匹配则用Equals
                 //年龄区间查询
                .WhereIf(input.AgeStart.HasValue, s => s.Age >= input.AgeStart.Value)
                .WhereIf(input.AgeEnd.HasValue, s => s.Age <= input.AgeEnd.Value)
 
                //创建日期区间查询
                .WhereIf(input.CreationTimeStart.HasValue, s => s.CreationTime >= input.CreationTimeStart.Value)
                .WhereIf(input.CreationTimeEnd.HasValue, s => s.CreationTime <= input.CreationTimeEnd.Value)
                ;
        }

排序的处理,我们可以重写下规则如下所示。

        /// <summary>
        /// 自定义排序处理
        /// </summary>
        /// <param name="query">可查询LINQ</param>
        /// <param name="input">查询条件Dto</param>
        /// <returns></returns>
        protected override IQueryable<Customer> ApplySorting(IQueryable<Customer> query, CustomerPagedDto input)
        {
            if (!string.IsNullOrEmpty(input.Sorting))//排序字段是否有值
            {
                query = query.OrderBy(input.Sorting);
            }
            else
            {
                query = query.OrderByDescending(t => t.CreationTime);
            }
            return query;
        }

完成这些,我们就可以测试前端的界面效果了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK