SAPUI5 JS Объединение нескольких фильтров с ИЛИ - PullRequest
0 голосов
/ 18 октября 2018

Я хочу объединить несколько фильтров с or для моего запроса OData.Фильтры работают нормально, если я попробую их по отдельности.Теперь мне нужно их объединить.Это одиночные фильтры (aFilterBetween, aFilterLeftBorder, aFilterRightBorder):

var aFilterBetween = [];
aFilterBetween.push(new Filter({
    filters: [
        new Filter("StartDate", "GE", calenderStartDate),
        new Filter("EndDate", "LE", calenderEndDate)
    ],
    and: true
}));

var aFilterLeftBorder = [];
aFilterLeftBorder.push(new Filter({
    filters: [
        new Filter("StartDate", "LT", calenderStartDate),
        new Filter("EndDate", "GT", calenderStartDate)
    ],
    and: true
}));

var aFilterRightBorder = [];
aFilterRightBorder.push(new Filter({
    filters: [
        new Filter("StartDate", "LT", calenderStartDate),
        new Filter("EndDate", "GT", calenderEndDate)
    ],
    and: true
}));

Три фильтра должны быть объединены с or, чтобы в результате было показано все, что соответствует одному из этих трех фильтров.Комбинированный фильтр из этих трех должен использоваться для моего запроса OData, как показано ниже ...

oDataModel.read("/Initiatives", {
    filters: ***here has to be the filter***,
    urlParameters: {
        "$top": "50",
        "$select": "StartDate,EndDate"
    },
    success: function(oData, oResponse) {
    ... }

Я попытался соединить три фильтра (здесь даже только два), используя and: false, но почему-то это не удалосьработа для меня:

var aFilterCombined = [];
aFilterCombined.push(new Filter({
    filters: [
        aFilterBetween,
        aFilterLeftBorder
    ],
    and: false
}));

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Согласно SAP-ноте 2377685 :

Вы можете использовать операторы OR для применения разных фильтров к одному и тому же полю.Однако вы не можете использовать условие ИЛИ для применения фильтров к двум разным полям.Например: http://services.odata.org/OData/OData.svc/Products?$filter=Name eq 'Milk' или Name eq 'Bread'

Я сталкивался с этим ограничением пару раз, и это не имеет значения, если вы используете разработку сервиса (ручная реализацияв DPC_EXT) или создание службы (реализации, основанные на RFC, BOR, CDS и т. д.).

Что я рекомендую сделать, так это добавить новое «фиктивное» свойство в тип вашей сущности и установить фильтр только для этого свойства.В своем коде ABAP вы можете получить информацию из этого свойства и использовать ИЛИ для внутреннего использования.Поскольку у вас могут быть разные типы данных в столбцах, для которых вам нужно предложение OR, я рекомендую использовать тип 'Edm.String' в этом фиктивном свойстве.

Поэтому вместо выполнения вызова, подобного этому:

http://services.odata.org/OData/OData.svc/Products?$filter=Name eq «Молоко» или Name eq «Хлеб»

Вы можете обойтись с

http://services.odata.org/OData/OData.svc/Products?$filter=GenericFilterProperty eq «FilterValue»

В вашем конкретном случае «FilterValue», вероятно, очень длинная строка, поскольку вы используете несколько диапазонов дат.Не бойся.Вы можете представить критерии фильтра в виде объекта JavaScript, а затем преобразовать его в JSON.

var aFilterBetween = [];
aFilterBetween.push(new Filter({
    filters: [
        new Filter("StartDate", "GE", calenderStartDate),
        new Filter("EndDate", "LE", calenderEndDate)
    ],
    and: true
}));

var aFilterLeftBorder = [];
aFilterLeftBorder.push(new Filter({
    filters: [
        new Filter("StartDate", "LT", calenderStartDate),
        new Filter("EndDate", "GT", calenderStartDate)
    ],
    and: true
}));

var aFilterRightBorder = [];
aFilterRightBorder.push(new Filter({
    filters: [
        new Filter("StartDate", "LT", calenderStartDate),
        new Filter("EndDate", "GT", calenderEndDate)
    ],
    and: true
}));

// represent filters as a String
var sFilterValue = JSON.stringify(aFilterRightBorder);

затем ...

oDataModel.read("/Initiatives", {
    filters: [new Filter({
        path: "GenericFilterProperty",
        operator: "EQ",
        value: sFilterValue 
     })],
    urlParameters: {
        "$top": "50",
        "$select": "StartDate,EndDate"
    },
    success: function(oData, oResponse) {
    ... }

При таком подходе вам потребуется преобразовать JSONк какой-то структуре данных ABAP (рабочая область или внутренние таблицы).Для этого я рекомендую использовать класс cl_fdt_json , метод json_to_data .

0 голосов
/ 18 октября 2018

Попробуйте это:

var oFilterCombined = new Filter({
    filters: [
        oFilter1,
        oFilter2
    ],
    and: false
});

Также и другие фильтры, я бы создал объекты фильтра вместо их вставки в массивы и использовал бы константы sap вместо строк для операторов фильтров (https://sapui5.hana.ondemand.com/1.54.8/#/api/sap.ui.model.FilterOperator):

var oFilterSingle= new Filter({
            filters: [
                new Filter("XXX", FilterOperator.EQ, "bla"),
                new Filter("YYY", FilterOperator.EQ, "blub")
            ],
            and: true
        });

чтение должно выглядеть так:

oDataModel.read("/Initiatives", {
    filters: oFilterCombined,
    urlParameters: {
        "$top": "50",
        "$select": "StartDate,EndDate"
    },
    success: function(oData, oResponse) {
    ...
}

ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ:

Возможно, проблема не в коде ui5, а в бэкэнде. Если это не работает, напишитеПакет, который отправляет ваш браузер.

Если вы используете сервер ABAP с сервисом OData, сгенерированным SEGW: сопоставления не могут различаться между фильтрами and и or! Вам необходимо реализовать это вручную!

...