Transform Request для Autoquery дружественных

Мы работаем со сторонней сеткой (telerik kendo), которая имеет встроенный пейджинг / сортировку / фильтрацию. Она будет отправлять запросы определенным образом при выполнении вызова GET, и я пытаюсь определить, есть ли способ перевода эти запросы к дружественным запросам AutoQuery.

Запросить строковые параметры

Шаблон сортировки:

sort[{0}][field] and sort[{0}][dir]

Фильтрация:

filter[filters][{0}][field]
filter[filters][{0}][operator]
filter[filters][{0}][value]

Итак, это заполняется в строке запроса:

filter[filters][0][field]
filter[filters][0][operator]
filter[filters][0][value]

нужно будет перевести на.

FieldName=1  //      filter[filters][0][field]+filter[filters][0][operator]+filter[filters][0][value] in a nutshell (not exactly true)

Должен ли я манипулировать объектом querystring в плагине, удаляя фильтры (или просто добавляя нужные мне)? Есть ли лучший вариант здесь?

Я не уверен, что есть и чистый способ сделать это на стороне кендо.

1 ответ

Решение

Я объясню два пути, по которым я иду, я надеюсь увидеть лучший ответ.

Сначала я попытался изменить строку запроса в фильтре запросов, но не смог. В итоге мне пришлось запускать автозапросы вручную, получая параметры и изменяя их перед вызовом AutoQuery.Execute. Что-то вроде этого:

var requestparams = Request.ToAutoQueryParams();
var q = AutoQueryDb.CreateQuery(requestobject, requestparams);
AutoQueryDb.Execute(requestobject, q);

Я хотел бы, чтобы был более глобальный способ сделать это. Метод extension просто перебирает все параметры строки запроса и добавляет те, которые мне нужны.

После выполнения вышеупомянутой работы я не был очень доволен результатом, поэтому я исследовал, как делать это по-другому, и в итоге получил следующее:

Зарегистрируйте операции фильтра сетки Kendo для их эквивалентных операций автоматического запроса стека служб:

 var aq = new AutoQueryFeature { MaxLimit = 100, EnableAutoQueryViewer=true };
        aq.ImplicitConventions.Add("%neq", aq.ImplicitConventions["%NotEqualTo"]);
        aq.ImplicitConventions.Add("%eq", "{Field} = {Value}");

Далее, в операции чтения таблицы нам нужно переформатировать строку запроса:

read: {
                                url: "/api/stuff?format=json&isGrid=true",
                                data: function (options) {
                                    if (options.sort && options.sort.length > 0) {
                                        options.OrderBy = (options.sort[0].dir == "desc" ? "-" : "") + options.sort[0].field;
                                    }
                                    if (options.filter && options.filter.filters.length > 0) {
                                        for (var i = 0; i < options.filter.filters.length; i++) {
                                            var f = options.filter.filters[i];
                                            console.log(f);
                                            options[f.field + f.operator] = f.value;
                                        }
                                    }

                                }

Теперь сетка будет отправлять операции в удобной для Autoquery форме.

Я создал ts-класс AutoQueryDataSource, который может вам пригодиться, а может и нет.

Его использование выглядит следующим образом:

this.gridDataSource = AutoQueryKendoDataSource.getDefaultInstance<dtos.QueryDbSubclass, dtos.ListDefinition>('/api/autoQueryRoute', { orderByDesc: 'createdOn' });


export default class AutoQueryKendoDataSource<queryT extends dtos.QueryDb_1<T>, T> extends kendo.data.DataSource {
    private constructor(options: kendo.data.DataSourceOptions = {}, public route?: string, public request?: queryT) {
        super(options)
    }

    defer: ng.IDeferred<any>;
    static exportToExcel(columns: kendo.ui.GridColumn[], dataSource: kendo.data.DataSource, filename: string) {
        let rows = [{ cells: columns.map(d => { return { value: d.field }; }) }];
        dataSource.fetch(function () {
            var data = this.data();
            for (var i = 0; i < data.length; i++) {
                //push single row for every record
                rows.push({
                    cells: _.map(columns, d => { return { value: data[i][d.field] } })
                })
            }
            var workbook = new kendo.ooxml.Workbook({
                sheets: [
                    {
                        columns: _.map(columns, d => { return { autoWidth: true } }),
                        // Title of the sheet
                        title: filename,
                        // Rows of the sheet
                        rows: rows
                    }
                ]
            });
            //save the file as Excel file with extension xlsx
            kendo.saveAs({ dataURI: workbook.toDataURL(), fileName: filename });
        })
    }

    static getDefaultInstance<queryT extends dtos.QueryDb_1<T>, T>(route: string, request: queryT, $q?: ng.IQService, model?: any) {
        let sortInfo: {
            orderBy?: string,
            orderByDesc?: string,
            skip?: number
        } = {
        };

        let opts = {
            transport: {
                read: {
                    url: route,
                    dataType: 'json',
                    data: request
                },
                parameterMap: (data, type) => {
                    if (type == 'read') {
                        if (data.sort) {
                            data.sort.forEach((s: any) => {
                                if (s.field.indexOf('.') > -1) {
                                    var arr = _.split(s.field, '.')
                                    s.field = arr[arr.length - 1];
                                }

                            })
                        }//for autoquery to work, need only field names not entity names.

                        sortInfo = {
                            orderByDesc: _.join(_.map(_.filter(data.sort, (s: any) => s.dir == 'desc'), 'field'), ','),
                            orderBy: _.join(_.map(_.filter(data.sort, (s: any) => s.dir == 'asc'), 'field'), ','),
                            skip: 0
                        }

                        if (data.page)
                            sortInfo.skip = (data.page - 1) * data.pageSize,
                                _.extend(data, request);
                        //override sorting if done via grid
                        if (sortInfo.orderByDesc) {
                            (<any>data).orderByDesc = sortInfo.orderByDesc;
                            (<any>data).orderBy = null;
                        }
                        if (sortInfo.orderBy) {
                            (<any>data).orderBy = sortInfo.orderBy;
                            (<any>data).orderByDesc = null;
                        }
                        (<any>data).skip = sortInfo.skip;

                        return data;
                    }
                    return data;
                },
            },
            requestStart: (e: kendo.data.DataSourceRequestStartEvent) => {
                let ds = <AutoQueryKendoDataSource<queryT, T>>e.sender;

                if ($q)
                    ds.defer = $q.defer();
            },
            requestEnd: (e: kendo.data.DataSourceRequestEndEvent) => {
                new DatesToStringsService().convert(e.response);
                let ds = <AutoQueryKendoDataSource<queryT, T>>e.sender;

                if (ds.defer)
                    ds.defer.resolve();
            },
            schema: {
                data: (response: dtos.QueryResponse<T>) => {
                    return response.results;
                },
                type: 'json',
                total: 'total',
                model: model
            },
            pageSize: request.take || 40,
            page: 1,
            serverPaging: true,
            serverSorting: true
        }

        let ds = new AutoQueryKendoDataSource<queryT, T>(opts, route, request);
        return ds;
    }
}
Другие вопросы по тегам