2016-08-16 2 views
17

В настоящее время я пишу свое первое приложение с угловым 2. У меня есть OverviewComponent, которая имеет следующий простой шаблон:Угловая 2 перезагрузка маршрута по изменению параметра

<div class="row"> 
    <div class="col-lg-8"> 
    <router-outlet></router-outlet> 
    </div> 
    <div class="col-lg-4"> 
    <app-list></app-list> 
    </div> 
</div> 

при доступе к URL / мой маршрутизатор перенаправляет меня к /overview, который затем загружает карту в маршрутизаторе розетке. В поле есть список элементов, которые можно щелкнуть, чтобы отображать <app-detail> вместо компонента приложения. Поэтому я передаю идентификатор ссылочного json-файла в URL-адрес: /details/:id (на моих маршрутах).

Все перечисленные работы полностью прекрасны. Если я сейчас нажму на один из элементов списка, будут показаны детали, но когда я выберу другой элемент списка, представление не изменится на новые детали. URL-адрес изменяется, но содержимое не перезагружается. Как я могу добиться повторной инициализации компонента DetailComponent?

ответ

18

Согласно первому окончательному выпуску, это разрешено.

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

this.route.params.subscribe(params => { 
    this.param = params['yourParam']; 
    this.initialiseState(); // reset and set based on new parameter this time 
}); 
+0

Хотя это предлагаемое решение, вопрос, который у меня был, был моим компонентом (который имеет вышеприведенный код) загружался после того, как маршрут был изменен, и, таким образом, код в этом обещании не был уволен. –

+0

можете поделиться фрагментом кода для меня, чтобы понять? – gpanagopoulos

+1

Это, безусловно, более изящное и угловатое решение, хотя я бы скорее обменял 'resetComponentState()' на более обобщенную функцию 'initialize', которая вызывается всякий раз, когда компонент создается или параметры изменены. – hGen

2

В настоящее время это не поддерживается напрямую. Смотрите также https://github.com/angular/angular/issues/9811

Что вы можете сделать что-то вроде

<div *ngIf="doShow" class="row"> 
    <div class="col-lg-8"> 
    <router-outlet></router-outlet> 
    </div> 
    <div class="col-lg-4"> 
    <app-list></app-list> 
    </div> 
</div> 
doShow:boolean: true; 

constructor(private _activatedRoute: ActivatedRoute, private _router:Router, private cdRef:ChangeDetectorRef) { 
    _router.routerState.queryParams.subscribe(
    data => { 
     console.log('queryParams', data['st']); 
     this.doShow = false; 
     this.cdRef.detectChanges(); 
     this.doShow = true; 
    }); 
} 

(не тестировался)

+0

Спасибо за быстрый ответ, но я решил эту проблему по-другому, см. мой ответ. – hGen

6

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

Мне удалось добиться «поддельной» перезагрузки следующим образом.

То, что я в основном сделал это создание компонент, который перенаправляет меня в «реальной» компонента Я хочу использовать:

@Component({ 
    selector: 'camps-fake', 
    template: '' 
}) 
export class FakeComponent implements OnInit { 

    constructor(private _router:Router, 
       private _route:ActivatedRoute) 
    { } 

    ngOnInit() { 
    let id:number = -1; 
    this._route.params.forEach((params:Params) => { 
     id = +params['id']; 
    }); 

    let link:any[] = ['/details', id]; 
    this._router.navigate(link); 
    } 

} 

Так, выбрав элемент списка маршрутизатор будет перемещаться к /fake/:id, который только извлекает идентификатор от URL-адреса и переходит к «реальному» компоненту.

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

+0

Хорошо, спасибо за этот совет! Жаль, что Angular не поддерживает это по умолчанию с каким-то событием. – YoannFleuryDev

+0

Прошло 6 месяцев, есть ли новости по этому поводу? Я использую ваш подход в настоящее время, но это не удобно. –

+0

@ RaymondtheDeveloper Не то, что я знаю. Сегодня я столкнулся с проблемой и дал еще один выстрел Google с такими же результатами. – hGen

2

Я решил это с помощью события, если дочерний компонент отправит новую ссылку и испустит событие, тогда родитель может найти изменение и вызвать некоторую функцию перезагрузки, которая перезагрузит необходимые данные. Другой вариант - подписаться на route parameters, and found when it change Но я думаю, что ребята из angular2 должны подумать о добавлении параметров в функцию router.navigate, что может заставить перезагрузить. (forceReload = true)

2

ли можно обнаружить какие-либо изменения в параметрах, полученных, в моем случае я загрузить информацию, используя Resolve таким образом я не требуется параметр (только если он изменится).Это мое окончательное решение:

public product: Product; 
private parametersObservable: any; 

constructor(private route: ActivatedRoute) { 
} 

ngOnInit() { 
    this.parametersObservable = this.route.params.subscribe(params => { 
    //"product" is obtained from 'ProductResolver' 
    this.product = this.route.snapshot.data['product']; 
    }); 
} 

//Don't forget to unsubscribe from the Observable 
ngOnDestroy() { 
    if(this.parametersObservable != null) { 
    this.parametersObservable.unsubscribe(); 
    } 
} 
+1

. Я не думаю, что отмена подписки необходима, так как маршрутизатор управляет наблюдаемыми, которые он предоставляет, и локализует подписки. Они очищаются, когда компонент уничтожается. См. Https://angular.io/tutorial/toh-pt5#do-you-need-to-unsubscribe –

2

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

providers: [ 
    { 
    provide: RouteReuseStrategy, 
    useClass: AARouteReuseStrategy 
    } 
] 

поведение по умолчанию маршрутизатора повторно маршрут, если конфигурация такая же (как в случае, когда только изменение: PARAM ID в этом вопросе). Изменяя стратегию, чтобы не повторно использовать маршрут, компонент будет перезагружен, и вам не нужно подписываться на изменения маршрута в компоненте.

Реализация в RouteReuseStrategy может выглядеть так:

export class AARouteReuseStrategy extends RouteReuseStrategy { 
    shouldDetach(route: ActivatedRouteSnapshot): boolean { 
    return false; 
    } 
    store(route: ActivatedRouteSnapshot, handle: {}): void { 

    } 
    shouldAttach(route: ActivatedRouteSnapshot): boolean { 
    return false; 
    } 
    retrieve(route: ActivatedRouteSnapshot): {} { 
    return null; 
} 
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { 
    return false; // default is true if configuration of current and future route are the same 
} 
} 

Я написал некоторые об этом здесь:

https://pjsjava.blogspot.no/2018/01/angular-components-not-reloading-on.html