Пользовательский фильтр AgGrid не создается до взаимодействия

У меня есть настраиваемый компонент фильтра для столбца в моей сетке. Я заметил, что компонент фильтра не создается, пока я не щелкну значок фильтра в заголовке столбца. Это означает, что данные не фильтруются в соответствии с моими настройками по умолчанию (например, фильтровать записи, где status == StatusEnum.Complete).

В качестве обходного пути я обнаружил, что могу получить экземпляр фильтра в событии onGridReady, вызвав api.getFilterInstance('status'), и это вызывает создание компонента фильтра и, таким образом, применение фильтрации по умолчанию.

Этот обходной путь кажется немного неуклюжим. Переменная filter не используется в событии onGridReady, которое вызывает предупреждения в среде IDE / build. Другой разработчик может прийти и удалить эту строку кода, посчитав это ненужным.

Есть ли лучший способ принудительно создать экземпляр моего настраиваемого фильтра при создании сетки? Я использую AgGrid 17.1 и Angular 4.4.

Сетка настроена так:

gridOptions: GridOptions = {
    enableFilter: true,
    onGridReady: (event) => {
        let filter = event.api.getFilterInstance("status"); // forces the filter component to be constructed
        let data = this.loadAsyncData();
        event.api.setRowData(data);
    },
    columnDefs: [
    ...
    {
        headerName: "Status",
        field: "status",
        filterFramework: MyCustomStatusFilterComponent,
        filterParams: {
            valueGetter: (obj) => { return obj.data.statusEnum; },
            hideCompleteByDefault: true,
            ...
        }
    },
    ....
    ]
}

Я создал пример, демонстрирующий проблему. Обратите внимание на «взлом» в строке 63 app.component.ts.


person djs    schedule 14.02.2019    source источник
comment
Мне вроде бы интересно посмотреть на это, но у вас нет тестового примера, поэтому вам сложно помочь. Можете ли вы установить демонстрацию, показывающую проблему? Вы можете начать из этого или любого другого примера из документация.   -  person thirtydot    schedule 22.02.2019
comment
Добавлен @thirtydot plunkr. Благодарность!   -  person djs    schedule 22.02.2019


Ответы (3)


Прежде всего - это две независимые вещи, настраиваемый фильтр и инициализация фильтра.

Полагаю, вы смешали эти две фазы и пытаетесь добиться неожиданного результата.

Ваш настраиваемый фильтр не должен содержать предопределенную логику cuz init произойдет только при первом прикосновении к вашему фильтру, вам нужно разделить свою логику, а затем в onGridReady вы можете выполнить setModel с необходимыми вещами. или сохраните хак, как вы уже упомянули

person un.spike    schedule 23.02.2019
comment
Похоже, этот подход у меня сработает. Тем не менее, мне все еще любопытно, почему фильтры не инициализируются до тех пор, пока они не будут впервые затронуты. Это где-то в документации ag-grid? - person djs; 26.02.2019
comment
@djs: я не вижу этого явно в документации, но это не имеет значения. Если вы посмотрите в исходный код, он инициализируется по запросу, и это почти наверняка из соображений производительности. Посмотрите на самую первую функцию, которую они перечисляют: ag-grid.com/features-overview (Выдающаяся производительность). Подумайте об этом: установленный фильтр должен пройти через все ваши (установите его на: 100 000) строки для сбора уникальных значений. Если у вас есть 22+ столбца, сетка будет отставать при запуске (особенно на медленном оборудовании). - person thirtydot; 26.02.2019

Основная проблема в том, что вы боретесь против того, как компоненты фильтра работают по умолчанию. Ag-grid прилагает значительные усилия для создания графического интерфейса фильтра по запросу (когда вы щелкаете значок фильтра столбца). Это сделано для того, чтобы избежать потери производительности из-за того, что 100 различных компонентов фильтра бессмысленно инициализируются при запуске сетки (если у вас 100 столбцов).

Если вы хотите сохранить настройки фильтра (отфильтровать «Завершенные») внутри вашего настраиваемого компонента фильтра, то придерживайтесь того, что у вас есть. Сомневаюсь, что есть способ получше.

Однако на самом деле вам следует переместить условие фильтра за пределы настраиваемого компонента фильтра. Представьте, что у вас есть другая страница, где по умолчанию вы хотите использовать другую фильтрацию в столбце «Статус». Это будет сложно сделать с вашим текущим дизайном.

Ваш код должен выглядеть примерно так:

onGridReady(params) {
    this.gridApi = params.api;
    this.gridColumnApi = params.columnApi;

    // hack to get default filtering
    //params.api.getFilterInstance('status');

    params.api.setRowData(this.rowData);

    // apply filter model
    // use same filter model that enterprise set filter uses, since your filter is similar
    params.api.setFilterModel({
        status: {
            filterType: 'customStatusFilter',
            values: ['New', 'Working on it'],
        },
    });

    params.api.sizeColumnsToFit();
}

Конечно, чтобы использовать это, вам придется существенно переписать свой настраиваемый компонент фильтра. Я попытался сделать это, но это занимало слишком много времени, и я действительно не знаю Angular, поэтому отправляю свой ответ как есть. Ваша текущая реализация вызовет у вас много проблем, если вы попытаетесь развить ее (или смешать с другими функциями ag-grid).

Может быть, эти ссылки помогут:

person thirtydot    schedule 23.02.2019
comment
Разве метод isFilterActive() не должен предотвращать сотни проверок при инициализации? Фильтры без фильтрации по умолчанию вернут false. Кроме того, не могли бы вы уточнить свое последнее предложение? Your current implementation will cause you a lot of problems if you try to build upon it (or mix it with other ag-grid features) На самом деле я успешно использую это в нескольких местах с разными перечислениями статуса и параметрами фильтрации по умолчанию. - person djs; 25.02.2019
comment
Я также должен отметить, что созданный мной plunkr - это MCVE, чтобы продемонстрировать проблему того, что фильтр не инициализируется при создании сетки. В моем фактическом коде есть некоторые другие абстракции и шаблоны, которые делают его более пригодным для повторного использования в рамках ag-grid. - person djs; 25.02.2019
comment
Как вы используете разные перечисления состояний, когда они жестко запрограммированы в вашем компоненте фильтра? Попробуйте объединить два разных столбца состояния в одну сетку без дублирования файла компонента пользовательского фильтра. Попробуйте использовать setFilterModel, чтобы установить диапазон фильтров в вашей сетке. Попробуйте сбросить все фильтры, чтобы фильтрация была нулевая. Попробуйте использовать setColumnDefs, чтобы добавить в конец дополнительный столбец. Как насчет того, когда вам понадобится фильтрация этого стиля флажка в другом столбце? - person thirtydot; 25.02.2019
comment
На самом деле у этого есть две стороны. С одной стороны, ваш код работает для вашего текущего варианта использования. С другой стороны, то же самое происходило с большей частью кода на thedailywtf.com, ... пока этого не произошло. Вся суть вашего вопроса заключалась в том, что вам не понравился ваш взлом и что другой разработчик может его удалить. Весь ваш компонент фильтра - это взлом! Конечно, я сравниваю его с корпоративным фильтром, что, естественно, несправедливо. Если ваша сетка является началом сложного проекта, это имеет большее значение. Если это всего лишь быстрая разовая страница, это не имеет значения. ¯ \ _ (ツ) _ / ¯ - person thirtydot; 25.02.2019
comment
(Я написал эти комментарии до вашего последнего комментария). - person thirtydot; 25.02.2019

Здесь вы используете настраиваемую фильтрацию,

Если ваша строка не привязана к значению, вы используете настраиваемую фильтрацию.

         {
            headerName: "Date",
            field: "date",

            //Custom  Filter Start

            filterValueGetter: (params: ICellRendererParams) => 
            {
              if (this.transactionIsEmpty(params.data)) 
              {
                const tx: Transaction = params.data;
                return moment(tx.date).format('DD-MM-YYYY');
              }
            },

            //Custom  Filter End

            cellStyle: { 'text-align': 'left' },
            minWidth: 250,
        }
person Mayur Parmar    schedule 01.01.2021