В приведенном ниже коде используется один и тот же компонент
AppComponent
для трех разных маршрутов, включая/
,/route2
и/route3
.Проблема в том, что свойства
title
иbodyHTML
AppComponent
не изменяют значения при выборе разных маршрутов.Какие конкретные изменения необходимо внести в код ниже, чтобы приложение обслуживало разные значения для
title
иbodyHTML
, когда пользователь выбирает каждый из разных маршрутов?Ниже приведены шаги, чтобы воспроизвести проблему на любом компьютере за несколько минут:
Создать приложение Seed:
Сначала я создал начальное приложение с помощью Angular -CLI в следующих шагах:
cd C:\projects\angular-cli
ng new routes-share-component
cd C:\projects\angular-cli\routes-share-component
ng serve
Изменить только 4 файла:
Затем я изменил только 4 файла следующим образом:
Я добавил app.routing.ts
со следующим содержанием:
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
const appRoutes: Routes = [
{ path: '', component: AppComponent },
{ path: 'route2', component: AppComponent },
{ path: 'route3', component: AppComponent }
];
export const routing = RouterModule.forRoot(appRoutes);
Я изменил app.component.ts
, чтобы стать следующим:
import { Component, OnInit, OnChanges } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Router } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnChanges {
title = 'This is the title!';
bodyHTML = 'Here is the content!'
constructor(private _router:Router, private route:ActivatedRoute) {
console.log('inside the constructor!');
console.log(route.url);
console.log(_router.url);
}
ngOnInit() {
console.log('inside ngOnInit()');
let currentUrl = this._router.url; /// this will give you current url
console.log(currentUrl);
if(currentUrl=='/'){this.title='Home Page Title';this.bodyHTML='Body goes here.';}
if(currentUrl=='/route2'){this.title='Route 2 Title';this.bodyHTML='Body goes here.';}
if(currentUrl=='/route3'){this.title='Route 3 Title';this.bodyHTML='Body goes here.';}
console.log(this.route.url);
}
ngOnChanges() {
console.log('inside ngOnChanges()!');
let currentUrl = this._router.url; /// this will give you current url
console.log(currentUrl);
if(currentUrl=='/'){this.title='Home Page Title';this.bodyHTML='Body goes here.';}
if(currentUrl=='/route2'){this.title='Route 2 Title';this.bodyHTML='Body goes here.';}
if(currentUrl=='/route3'){this.title='Route 3 Title';this.bodyHTML='Body goes here.';}
console.log(this.route.url);
}
}
Аналогично, app.component.html
было упрощено следующим образом:
<div style="text-align:left">
<h1>{{title}}</h1>
<p>{{bodyHTML}}</p>
</div>
И app.module.ts
становится следующим, при включенном app.routing.ts
:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule, routing
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Обратите внимание, что блок ngOnInit()
печатает в консоли, но блок ngOnChanges()
НЕ. Это означает, что заголовок всегда Home Page Title
, независимо от того, какой маршрут выбран.
Какие конкретные изменения необходимо внести в вышеуказанный код, чтобы каждый маршрут печатал разные значения в браузере для title
и bodyHTML
?
Предложения @BeetleJuice:
В предложении @BeetleJuice я попробовал следующую новую версию AppComponent
, но она показывает ошибки компиляции в строках routerSub:Subscription
и в строке this.routerSub = this.router.events.filter(....)
.
import { Component, OnInit, OnChanges } from '@angular/core';
import { NavigationEnd, Router, ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'This is the title!';
bodyHTML = 'Here is the content!';
routerSub:Subscription;
constructor(private router:Router) {
console.log('inside the constructor!');
console.log(router.url);
}
ngOnInit(){
// listen to NavigationEnd events
this.routerSub = this.router.events.filter(e=>e instanceof NavigationEnd)
// capture the new URL
.map(e.NavigationEnd => e.url)
.subscribe(url => {
/* TODO: use URL to update the view */
});
}
// When the component is destroyed, you must unsubscribe to avoid memory leaks
ngOnDestroy(){
this.routerSub.unsubscribe();
}
}
Что еще нужно изменить?