仅按字符串的某些部分对表格进行排序 [英] Sort table by certain parts of string only

查看:43
本文介绍了仅按字符串的某些部分对表格进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用排序器进行排序基本正常.一列是全名(例如史蒂夫·乔布斯").我在该实体集中只有全名,但我想在单击全名列标题时按姓氏(全名的最后一个字)对条目进行排序.有没有办法做到这一点?

The sorting works basically fine using the sorter. One column is the full name (e.g. "Steve Jobs"). I have only the full name in that entity set but I want to sort the entries by the last name (last word of the full name) when clicking the full name column header. Is there some way to do this?

推荐答案

您需要为排序器定义一个自定义比较器,它仅当所有实体都可用 客户端时才适用,例如例如,通过在定义 OData 列表绑定时将 operationMode 设置为 'Client'.API

You'll need to define a custom comparator for the sorter which applies only if all the entities are available client-side, for example, by having the operationMode set to 'Client' when defining the OData list binding.API

sap.ui.getCore().attachInit(() => sap.ui.require([
  "sap/ui/model/odata/v2/ODataModel",
  "sap/ui/core/mvc/XMLView",
  "sap/ui/model/json/JSONModel",
  "sap/ui/model/Sorter",
], (ODataModel, XMLView, JSONModel, Sorter) => {
  "use strict";
  const odataModel = new ODataModel({
    serviceUrl: [
      "https://cors-anywhere.herokuapp.com/",
      "https://services.odata.org/V2/Northwind/Northwind.svc/",
    ].join(""),
    tokenHandling: false,
    preliminaryContext: true,
  });
  Promise.all([
    odataModel.metadataLoaded(),
    sap.ui.getCore().loadLibrary("sap.m", true),
  ]).then(() => XMLView.create({
    definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc"
      xmlns="sap.m"
      xmlns:core="sap.ui.core"
      height="100%"
    >
      <App>
        <Page showHeader="false">
          <Table id="myResponsiveTable"
            items="{
              path: '/Customers',
              parameters: {
                select: 'CustomerID, ContactName',
                operationMode: 'Client'
              }
            }"
          >
            <columns>
              <Column id="customerIdColumn"
                sortIndicator="{colCustomerId>/sortOrder}"
                width="33%"
              >
                <Text text="Customer ID">
                  <customData>
                    <core:CustomData
                      key="sorterPath"
                      value="CustomerID"
                    />
                  </customData>
                </Text>
              </Column>
              <Column id="fullNameColumn"
                sortIndicator="{colFullName>/sortOrder}"
                width="auto"
              >
                <Text text="Full Name">
                  <customData>
                    <core:CustomData
                      key="sorterPath"
                      value="ContactName"
                    />
                  </customData>
                </Text>
              </Column>
            </columns>
            <ColumnListItem>
              <Text text="{CustomerID}" />
              <Text text="{ContactName}" />
            </ColumnListItem>
          </Table>
        </Page>
      </App>
    </mvc:View>`,
    afterInit: function() { // === onInit
      const table = this.byId("myResponsiveTable");
      activateColumnPress(table, onColumnPress);
    },
    models: {
      undefined: odataModel,
      colCustomerId: new JSONModel({ sortOrder: "None" }),
      colFullName: new JSONModel({ sortOrder: "None" }),
    }
  }).then(view => view.placeAt("content")));

  function activateColumnPress(table, handler) {
    // Making columns clickable for the demo
    table.bActiveHeaders = true;
    table.onColumnPress = col => handler(table, col);
  }
  
  function onColumnPress(table, pressedCol) {
    table.getColumns()
      .filter(col => !(col.getSortIndicator() === pressedCol.getSortIndicator()))
      .map(col => col.setSortIndicator("None"));
    table.getBinding("items").sort(createSorter(pressedCol));
  }

  function createSorter(column) {
    return column.getHeader().data("sorterPath") === "ContactName"
      ? createFullNameSorter(column, toggleSort(column.getModel("colFullName")))
      : createCustomerIdSorter(column, toggleSort(column.getModel("colCustomerId")));
  }

  function toggleSort(colModel) {
    const descending = colModel.getProperty("/sortOrder") !== "Ascending";
    colModel.setProperty("/sortOrder", descending ? "Ascending" : "Descending");
    return !descending;
  }

  function createFullNameSorter(column, descending) {
    const comparator = (a, b) => a.split(" ").pop().localeCompare(b.split(" ").pop());
    return new Sorter("ContactName", descending, false, comparator);
  }

  function createCustomerIdSorter(column, descending) {
    return new Sorter("CustomerID", descending);
  }

}));

<script id="sap-ui-bootstrap"
  src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
  data-sap-ui-libs="sap.ui.core"
  data-sap-ui-async="true"
  data-sap-ui-compatversion="edge"
  data-sap-ui-theme="sap_belize"
  data-sap-ui-xx-waitfortheme="true"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact" style="height: 100%;"></body>

顺便说一句:目前的客户端"操作模式不获取所有实体 如果服务已实现服务器端分页.

Btw: the "Client" operation mode currently doesn't fetch all entities if the service has server-side paging implemented.

如上例所示,Sorter 构造函数 可以处理自定义比较器,该比较器将在调用 sort 方法时调用.为了比较全名的最后部分,您可以像这样定义比较器:

As you can see in the example above, the Sorter constructor can handle custom comparator which will be invoked when the sort method is called. For comparing last parts of the full names, you can define the comparator like this:

function compare(fullName_a, fullName_b) {
  const lastPart_a = fullName_a.split(" ").pop();
  const lastPart_b = fullName_b.split(" ").pop();
  return lastPart_a.localeCompare(lastPart_b); // 0 if equal. Otherwise a negative or positive number
}

这篇关于仅按字符串的某些部分对表格进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆