2

У меня есть небольшой Plunk, который я использую для игры с новой альфа-маршрутизатором 3.0, доступной в настоящее время в Angular 2. Это хорошо работает в целом, но проблема заключается в том, что после того, как я нажму ссылку, которая направляется к компоненту «detail» с определенным идентификатором, он никогда не изменяется, когда я нажимаю на другую ссылку с другим идентификатором. Компонент никогда не восстанавливается, поэтому он только когда-либо показывает, что он был передан в первый раз, когда он загружен.Компонент Angular2 не обнаруживает обновления параметров маршрутизации (Router 3.0)

Вот компонент вопрос:

import { Component, OnInit } from '@angular/core'; 
import { ActivatedRoute } from '@angular/router'; 
import { ContactsService } from './contacts.service'; 

@Component({ 
    selector: 'contacts-detail', 
    template: ` 
    <h2>{{contact.name}}</h2> 
    ` 
}) 
export class ContactsDetailComponent implements OnInit { 

    constructor(private contactsService: ContactsService, private route: ActivatedRoute) { 
    } 

    ngOnInit() { 
    this.contact = this.contactsService.getContact(this.route.snapshot.params.id); 
    console.log('Fetching user', this.route.snapshot.params.id); 
    } 
} 

Here is the Plunk демонстрирует проблему. Нажмите одно имя автора, а затем другое, чтобы увидеть, что оно не изменяется.

ответ

8

В вашем ContactsDetailComponent, изменить OnInit к этому:

ngOnInit() { 
    this.sub = this.route.params.subscribe(params => { 
    let id = +params['id']; 
    this.contact = this.contactsService.getContact(id); 
    }); 
    } 

Работал для меня в вашем шлепнуть.

+0

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

+0

Это не странно, это повторное использование компонентов. – TDaver

+0

@TDaver Позвольте мне изменить свой выбор слов; это совсем не очевидно. Я искал что-то вроде интерфейса ngOnReload для работы, но ничего не нашел. Казалось бы, это еще более угловатый способ сделать то, что нужно сделать. –

1

Кажется, что для этого могут использоваться несколько крючков жизненного цикла. Мне удалось получить желаемое поведение с использованием интерфейса DoCheck и реализовать связанный с ним метод ngDoCheck() в классе компонентов, как показано ниже.

import { Component, DoCheck } from '@angular/core'; 
import { ActivatedRoute } from '@angular/router'; 
import { ContactsService } from './contacts.service'; 

@Component({ 
    selector: 'contacts-detail', 
    template: ` 
    <h2>{{contact.name}}</h2> 
    ` 
}) 
export class ContactsDetailComponent implements AfterViewChecked, DoCheck { 

    constructor(private contactsService: ContactsService, private route: ActivatedRoute) { 
    } 

    ngDoCheck() { 
    this.contact = this.contactsService.getContact(this.route.snapshot.params.id); 
    } 
} 

Here's a plunk с обновленным кодом.

Я не уверен, что это лучший/правильный крюк жизненного цикла для использования. Возможно, есть какой-то крючок, доступный от Router, который будет служить этому лучше.

+0

Это интересный подход (и он, очевидно, работает). Из небольшого количества документации имеется около 'DoCheck', похоже, что он предназначен для использования с директивами. Любая идея, если есть преимущество в получении значений параметров из моментального снимка и наблюдаемого? –

+0

@ R.Richards Я не уверен, что это правильная вещь вообще. Я проверил поле формы в компоненте, связанном с переменной '@ Input', и метод' ngDoCheck() 'срабатывал при каждом нажатии клавиши в поле ввода, что явно не то, что мы действительно хотим. Там просто «чувствует», как будто должно быть что-то лучше, но я видел статью (не официальную) о том, что новый маршрутизатор ожидает, что люди справятся с такой ситуацией, как вы это делаете в своем ответе ... –

+1

Wow. Спасибо @ Майкл Орил !! Я хотел бы купить тебе чашку кофе.Я пытался заставить один из моих компонентов обновиться, когда изменилось одно из его значений, и после многочисленных попыток, которые я почти полностью отказался. Я попробовал реализовать метод ngDoCheck(), как вы предлагали, и теперь он просто работает. Виола. Несколько часов разочарования подошли к концу. – b0rgBart3

0

Другим способом сделать это:

ngOnInit() { 
    this.route.params.forEach((params: Params) => { 
     let id = +params['id']; 
     this.contact = this.contactsService.getContact(id); 
    }); 
} 

Здесь извлечь Params маршрута из наблюдаемых. Преимущество использования Observable over Snapshot заключается в повторном использовании компонента без его повторного использования. Похоже, это рекомендуемый способ сделать это в соответствии с окончательной документацией Angular 2.0.

Смежные вопросы