仅按字符串的某些部分对表进行排序

问题描述 投票:1回答:1

使用分拣机,分拣工作基本上很好。一列是全名(例如“史蒂夫·乔布斯”)。我只有该实体集中的全名,但我想在单击全名列标题时按姓氏(全名的最后一个单词)对条目进行排序。有办法做到这一点吗?

sapui5
1个回答
1
投票

您需要为分拣机定义一个自定义比较器,仅当所有实体都在客户端可用时才适用,例如,在定义OData列表binding.operationMode时将'Client'设置为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>

顺便说一句:如果服务实现了服务器端分页,则“客户端”操作模式当前为doesn't fetch all entities

正如您在上面的示例中所看到的,Sorter constructor可以处理自定义比较器,该比较器将在调用sort方法时调用。为了比较全名的最后部分,您可以像这样定义比较器:

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
}
© www.soinside.com 2019 - 2024. All rights reserved.