Перезагрузите компонент с другими параметрами маршрута в angular4

Я использую маршрутизацию angular2. Когда пользователь повторно вводит значение в поле поиска и нажимает на поиск, тот же компонент необходимо перезагрузить, но с другими параметрами маршрута.

<button (click)="onReload()">Search</button>

onReload() {
this.router.navigate(['results',this.location]);
}

Это мой путь маршрута для моего ResultsComponent

{ path:'results/:location', component:ResultsComponent}

Эта функция изменяет URL-адрес, но не выполняет повторную инициализацию компонента.

В angularjs, ui-router я мог добиться этого следующим образом.

$state.go($state.current, location, {reload: true});

Как мне это сделать в angular4?


person CKA    schedule 03.08.2017    source источник
comment
у нас такая же проблема :(   -  person vistajess    schedule 03.08.2017
comment
@vistajess Скажи мне, если найдешь решение.   -  person CKA    schedule 03.08.2017


Ответы (3)


Вам необходимо выполнить логику инициализации в функции обратного вызова подписки в функции обратного вызова подписки наблюдаемого потока route.params.

В вашем классе компонентов

@Component({
  ...
})
export class MyComponent implements OnInit {

   myLocation:string;

   constructor(private route:ActivatedRoute) {}

   ngOnInit() {
     this.route.params.subscribe((params:Params) => {
        this.myLocation = params['location'];
        // -- Initialization code -- 
        this.doMyCustomInitialization();
     }
   }

   private doMyCustomInitialization() {
       console.log(`Reinitializing with new location value ${this.location}`);
   }
}

С другой стороны, если вам нужно разрешить данные на основе значения «местоположения», вы должны использовать защиту разрешения, которая разрешает данные до создания компонента. Подробнее см. https://angular.io/guide/router#resolve-guard. информация о разрешающих охранниках и маршрутизации.

Вот рабочий планкр. https://plnkr.co/edit/g2tCnJ?p=preview

person JeanPaul A.    schedule 03.08.2017
comment
Я подписываюсь на параметры. Мой URL также меняется на новые параметры. Но компонент не инициализируется повторно. - person CKA; 03.08.2017
comment
Вам необходимо выполнить логику инициализации, основанную на значении местоположения в функции обратного вызова подписки. Таким образом, всякий раз, когда изменяется маршрут (и, следовательно, параметры), логика инициализации выполняется повторно. Для эффективности angular не уничтожает и не воссоздает компонент, если маршрут, к которому осуществляется переход, привязан к тому же компоненту. - person JeanPaul A.; 03.08.2017
comment
Я попытался поместить логику инициализации в обратный вызов подписки. Это все еще не работает. Также моя логика инициализации — это вызов службы http, которой я передаю местоположение и получаю данные. - person CKA; 03.08.2017
comment
В вашем случае вам нужно использовать защиту разрешения, которая может использовать значение местоположения. Смотрите ссылку, которую я разместил в ответе выше. - person JeanPaul A.; 03.08.2017
comment
Охранники используются для остановки маршрутизации до тех пор, пока ваши асинхронные задачи не будут завершены. В моем случае асинхронную задачу необходимо выполнить после изменения маршрута. Итак, я не знаю, как Resolve Guard может помочь мне в этом. - person CKA; 04.08.2017
comment
Это правильно, это поведение охранника. При изменении маршрута (в данном случае в другом месте) охрана снова разрешает данные (поскольку это считается новым маршрутом). Есть ли причина, по которой вы хотите загружать данные после завершения маршрута (и, следовательно, создания компонента), а не разрешать их заранее? - person JeanPaul A.; 04.08.2017
comment
Ранее вы упомянули, что размещение вашей логики инициализации в блоке подписки не сработало. Как это так? (потому что событие, если это http-вызов, все равно должно работать). Не могли бы вы предоставить код, пожалуйста? :) - person JeanPaul A.; 04.08.2017
comment
Давайте продолжим обсуждение в чате. - person JeanPaul A.; 04.08.2017

ОТРЕДАКТИРОВАНО

Угловой способ сообщить маршрутизатору сделать это — использовать onSameUrlNavigation с angular 5.1.

Но мне пришлось решить эту проблему по-другому (Stackblitz), от subscribing до route events и фактически вызывая custom reInit method.

Хитрость заключается в том, чтобы добавить все подписки на один и тот же объект, а затем отменить подписку ТОЛЬКО тогда, когда ngOnDestroy вызывается angular, а остальные переменные вашего шаблона изменяются с custom destroy method...

    public subscribers: any = {};

    constructor(private router: Router) {
    /** 
      * This is important: Since this screen can be accessed from two menu options 
      * we need to tell angular to reload the component when this happens.
      * It is important to filter the router events since router will emit many events,
      * therefore calling reInitComponent many times wich we do not want.
      */   
      this.subscribers._router_subscription = this.router.events.filter(evt => evt instanceof NavigationEnd).subscribe((value) => { 
        this.reInitComponent();
      });
    }

    reInitComponent() {
        this.customOnDestroy();
        this.customOnInit();
    }

    customOnInit() {
        // add your subscriptions to subscribers.WHATEVERSUB here
        // put your ngOnInit code here, and remove implementation and import 
    }

    customOnDestroy() {
      // here goes all logic to re initialize || modify the component vars  
    }

    /**
     * onDestroy will be called when router changes component, but not when changin parameters ;)
     * it is importatn to unsubscribe here
     */
     ngOnDestroy() {  
       for (let subscriberKey in this.subscribers) {
          let subscriber = this.subscribers[subscriberKey];
          if (subscriber instanceof Subscription) {
            subscriber.unsubscribe();
          }
        }
     }

Обратите внимание, что если вы реализуете обработчик жизненного цикла ngOnInit, вы должны удалить его и реализовать собственный метод, как в примере.

Я добавил метод unsubscription из-за этой ошибки angular. Angular должен фактически автоматически отписываться от router.events при уничтожении компонента, но, поскольку это не так, если вы не отмените подписку вручную, вы в конечном итоге будете вызывать http-запросы (например) столько раз, сколько вы ввели компонент.

person Lucas    schedule 20.02.2018
comment
При простом использовании onSameUrlNavigation это решение @CKA, если это работает, pl. отметьте это как правильный ответ. - person Mohan Ram; 11.09.2019

https://angular-2-training-book.rangle.io/handout/routing/routeparams.html

В вашем компоненте вам нужно подписаться на параметры, чтобы определить, были ли они изменены.

person Justin    schedule 03.08.2017
comment
Я подписываюсь на параметры. Мой URL также меняется на новые параметры. Но компонент не инициализируется повторно - person CKA; 03.08.2017
comment
Спасибо за информацию. Я забыл подписаться на параметры в конструкторе. - person Gopal; 22.03.2019