Как обрабатывать несколько queryParams в Angular2

Я пытаюсь реализовать механизм фильтрации в новом приложении Angular2, который позволил бы мне фильтровать список записей в массиве. Записи могут иметь около 20 свойств, которые можно фильтровать. До сих пор я создал список фильтров в одном компоненте, а затем компонент списка, который направляется в качестве дочернего элемента. Затем я планировал передать фильтры как queryParams через маршрутизатор. Начиная с одного фильтра, все было в порядке:

На стороне отправки у меня было:

this.router.navigate(['/findlist'], {queryParams: {'g': myParam}});

На принимающей стороне у меня было:

this.subscription = this.route.queryParams.subscribe(
  (queryParam: any) => this.myFilter = queryParam['g']
);

Затем я передаю myFilter каналу фильтра, чтобы выполнить сопоставление и фильтрацию. Пока все в порядке.

Однако я не могу понять, как масштабировать это, чтобы учесть несколько потенциальных параметров, большинство из которых будут пустыми/не нужными.

Я могу себе представить, что мне нужно будет определить массив, содержащий ВСЕ активные фильтры через queryParam, но единственная документация, которую я могу найти, показывает только примеры с одним переданным параметром. Я пробовал играть с:

{queryParams: { pass an array here! }}

Но моя IDE регистрирует ошибку, если я добавляю что-то кроме пары ключ:значение.

Вероятно, я мог бы просто добавлять все возможные фильтры и их значения каждый раз, но это каждый раз создавало бы глупо длинную строку URL с большинством пустых значений или «Все» и т. д., что не очень красиво.

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

На стороне приема я каким-то образом должен получать и обрабатывать Param как массив, а затем извлекать каждую запись как переменные для последующей обработки в фильтре. Я также хочу быть СУХИМ, поэтому на самом деле не хочу, чтобы несколько операторов на стороне приема эффективно выполняли одно и то же для разных свойств, проще говоря, вместо этого имеет смысл циклически перемещаться по массиву.

Я надеюсь, что это имеет смысл, я был бы признателен, если бы у кого-нибудь есть предложение, даже если это означает передачу данных по-другому. Например, в настоящее время я пытаюсь понять, могу ли я просто передать данные, создав отдельную службу фильтрации и передав ее с помощью @Input вместо этого.

Любые идеи с благодарностью получены (любитель-самоучка, поэтому, вероятно, упустил что-то очевидное!)

Спасибо

Тони


person Tony Jackson    schedule 21.12.2016    source источник
comment
Возможное простое решение, вы могли бы передать все свои параметры как один параметр, разделенный трубой или что-то в этом роде? key_val|key_val|key_val или что-то в этом роде. Затем просто возьмите это значение параметра, разделите его на канал, а затем разделите каждое значение на знаке подчеркивания. Вы можете делать это прямо до тех пор, пока не будет установлен предел размера параметра маршрутизатора (каким бы он ни был). (Я бы подумал, что это не сработает, но вы даже можете попробовать это как строку json, хотя я знаю, что это полная неудача).   -  person Tim Consolazio    schedule 21.12.2016
comment
Вам нужно, чтобы URL-адрес отличался для разных комбинаций фильтров? Если нет, то можно воспользоваться сервисом удержания фильтров.   -  person Aluan Haddad    schedule 08.03.2017


Ответы (2)


Вы можете попробовать это так:

Определите массив с вашими параметрами запроса:

myQueryParams = [
    { id: 1, param: 'myParam' },
    { id: 2, param: 'myParam' },
    { id: 3, param: 'myParam' },
    { id: 4, param: 'myParam' },
    { id: 5, param: 'myParam' },
];

Поместите этот массив в один параметр запроса:

this.router.navigate(['/findlist'], {
    queryParams: {
        filter: JSON.stringify(this.myQueryParams)
    }
});

Прочитайте параметр запроса следующим образом:

this.route.queryParams.subscribe((p: any) => {
    if (p.filter){
        console.log(JSON.parse(p.filter));
    }
});

Вы увидите что-то вроде этого:

Скриншот инструментов разработчика Chrome

Теперь вы можете разобрать этот объект. Я думаю, что URL-адрес выглядит немного уродливым, но он должен быть функциональным. Попробуйте, надеюсь, вам поможет ;)

person Philipp Kief    schedule 22.12.2016
comment
Спасибо за ответ. Я попробовал это быстро, и да, это работает, и да, URL-адрес действительно уродлив! Я не думаю, что хотел бы продолжать с URL-адресами, как они есть в этом решении, поэтому подожду, чтобы узнать, есть ли у кого-нибудь другая идея. Я также рассмотрю возможность создания службы фильтрации, если я смогу заставить ее работать в фоновом режиме. Еще раз спасибо! - person Tony Jackson; 23.12.2016
comment
@TonyJackson, вы можете сделать это this.router.navigate(['/findlist'], { queryParams: { param1: 'value1', 'param2': 'value2' } }); и тогда URL будет выглядеть как localhost:4200/findlist?param1=value1¶m2=value2 - person Ifesinachi Bryan; 10.09.2018

Попробуй это.

this.router.navigate(['/findlist'], { queryParams: { param1: 'value1', 'param2': 'value2' } }); 

и тогда URL-адрес будет выглядеть

localhost:4200/findlist?param1=value1&param2=value2 

Наконец, вы можете вернуть параметры маршрута, используя приведенный ниже фрагмент кода:

this.route.queryParams.subscribe((p: any) => {
    if (p.param1){
        console.log(JSON.parse(p.param1));
    }
 if (p.param2){
        console.log(JSON.parse(p.param2));
    }
});
person Ifesinachi Bryan    schedule 10.09.2018