Angular 2 ngOnInit не вызывается при изменении маршрутизатора

у меня есть строка меню, которая содержит список меню, загруженных из express API, и каждое меню ссылается на страницу с псевдонимом, который будет URL-адресом этой страницы, я пытаюсь загрузить страницу, когда я нажимаю на меню, это делается, но только когда я обновляю страницу, это мой код меню

export class MenuList implements OnInit {

menus:Menu[];
menu:Menu;
page:Page;

constructor(private router:Router,
            private menuService:MenuService) {
}

getMenus():void {
    this.menuService.getMenus()
        .subscribe(
            menus => this.menus = menus, //Bind to view
            err => {
                // Log errors if any
                console.log(err);
            }
        );
}

getPage(id):void {
    this.menuService.getPage(id)
        .subscribe(
            page => this.page = page, //Bind to view
            err => {
                // Log errors if any
                console.log(err);
            });
}

ngOnInit():void {
    this.getMenus();
}

}

а это мой шаблон меню

<div class="container-fluid">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </button>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="navbar"  style="background-color: #97455f">
        <div class="navv">
            <ul *ngFor="let menu of menus">
                <li class="col-lg-1 col-md-1 col-xs-12 col-sm-12"><a [routerLink]="[menu.page.alias]">{{menu.title}}</a></li>


            </ul>
        </div>
    </div>

</div><!-- /.navbar-collapse -->

Я думаю, проблема в ngOnInit моего компонента страницы, он не вызывается

    @Component({
    selector: 'page',
    templateUrl: './page.component.html'
})
export class PageComponent implements OnInit {
    alias: string;
    page:Page;

    constructor(private router:Router,
                private route: ActivatedRoute,
                private pageService:PageService) {

        this.route.params.subscribe(
            (params : Params) => {
                this.alias = params["alias"];
                console.log(this.alias)
            }
        );
    }




    ngOnInit():void {
        debugger;
        this.pageService.getPage(this.alias).subscribe(page => {
            this.page = page;
            console.log(this.page);
        });
    }

}

а это мой шаблон страницы

    <p *ngIf="page" [innerHTML]="page.content" ></p>

это мой код маршрутизации приложения

const routes: Routes = [
    { path: '', redirectTo: '/home', pathMatch: 'full' },
    { path: ':alias', component: PageComponent },
    { path: 'archived',  component: ArchivedComponent },
    { path: 'home',  component: HomeComponent },
    { path: 'menu',  component: MenuList },
    { path: 'detail/:id', component: ActualiteDetailComponent },
    { path: 'contact',  component: ContactComponent },

];

@NgModule({
    imports: [ RouterModule.forRoot(routes) ],
    exports: [ RouterModule ]
})
export class AppRoutingModule {}

это мой компонент приложения

@Component({
  selector: 'my-app',
  template: `
    <menu-list></menu-list>
    <hr>
`

})
export class AppComponent {

}

Главная страница приложения со строкой меню


person Ilyes Atoui    schedule 24.08.2017    source источник
comment
Кстати. Порядок маршрутов имеет значение. Разве ни один маршрут в вашем приложении не проходит через PageComponent ? Даже домой, меню или контакт, например. Я имею в виду, что более конкретный маршрут должен быть вверху и более широкий внизу.   -  person Sharikov Vladislav    schedule 24.08.2017
comment
Я не могу понять из вашего вопроса, какой код/html отрезанный относится к какому компоненту и какое имя маршрута menu.page.alias может вернуться.   -  person Günter Zöchbauer    schedule 24.08.2017
comment
Шариков Владислав, да, все URL-адреса меню переходят от псевдонима к PageComponent, моя проблема в том, что содержимое страницы не загружается, когда я нажимаю в списке меню, но когда я обновляю страницу, она загружается   -  person Ilyes Atoui    schedule 24.08.2017


Ответы (3)


Вот пример кода того, о чем говорит Гюнтер:

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
     this.route.params.subscribe(
     params => {
        let id= +params['id'];
        this.getProduct(id);
     });
  }

Этот код отслеживает изменения параметров и выполняет любой код внутри стрелочной функции.

person DeborahK    schedule 24.08.2017
comment
Из предоставленной вами ссылки: subscribe will only take one argument: either the next handler (a function) or an observer object. Я передаю только один аргумент, поэтому приведенный выше синтаксис все еще должен быть в порядке. - person DeborahK; 08.04.2021

Когда изменяется только параметр маршрутизатора, но база маршрута остается неизменной, Angular повторно использует компонент. ngOnInit() вызывается только один раз после создания экземпляра компонента, но не при изменении маршрута.

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

person Günter Zöchbauer    schedule 24.08.2017
comment
Да, но как ? я должен использовать что-то еще вместо ngOnInit? резолвер например? - person Ilyes Atoui; 24.08.2017
comment
Вы можете ввести route:ActivatedRoute и подписаться на route.subscribe(...) - person Günter Zöchbauer; 24.08.2017
comment
Упс, я забыл `route.**params**.subscribe. Дебора все равно показывает полный код. Я думаю, что ее ответ, по крайней мере, заслуживает по крайней мере положительного голоса ;-) Рад слышать, что вы все равно смогли заставить его работать. - person Günter Zöchbauer; 24.08.2017

Хорошо, это исправлено благодаря @Günter Zöchbauer и @DeborahK. Я изменил код компонента страницы с этого

@Component({
selector: 'page',
templateUrl: './page.component.html'
    })
    export class PageComponent implements OnInit {
        alias: string;
        page:Page;

        constructor(private router:Router,
                    private route: ActivatedRoute,
                    private pageService:PageService) {

            this.route.params.subscribe(
                (params : Params) => {
                    this.alias = params["alias"];
                    console.log(this.alias)
                }
            );
        }

    ngOnInit():void {
            debugger;
            this.pageService.getPage(this.alias).subscribe(page => {
                this.page = page;
                console.log(this.page);
            });
        }
    }

к этому

@Component({
selector: 'page',
templateUrl: './page.component.html'
    })
    export class PageComponent implements OnInit {
        alias:string;
        page:Page;

        constructor(private router:Router,
                    private route:ActivatedRoute,
                    private pageService:PageService) {

            this.route.params.subscribe(
                (params:Params) => {
                    this.alias = params["alias"];
                    this.pageService.getPage(this.alias).subscribe(page => {
                        this.page = page;
                        console.log(this.page);
                    });
                    console.log(this.alias)
                }
            );
        }
         ngOnInit():void {
            this.pageService.getPage(this.alias).subscribe(page => {
                this.page = page;
                console.log(this.page);
            });
        }
    }
person Ilyes Atoui    schedule 24.08.2017
comment
Рад, что это работает для вас. Рассмотрите возможность переноса кода из конструктора в ngOnInit. Код для получения данных не должен находиться в конструкторе. Кроме того, вам не нужно повторять вызов метода getPage в файле ngOnIt. - person DeborahK; 24.08.2017
comment
Ой! Ага. Я забыл удалить его. Спасибо - person Ilyes Atoui; 25.08.2017