2017-07-11 47 views
2

下面的代碼提供了三種不同的途徑,包括//route2/route3同一組件AppComponent使用角2路由器爲不同的值傳遞到同一個組件

問題是當選擇不同的路由時AppComponenttitlebodyHTML屬性不會更改值。

需要對下面的代碼進行哪些特定的更改,以便當用戶選擇每個不同的路由時,應用程序將爲titlebodyHTML提供不同的值?

下面是重現問題任何計算機上幾分鐘步驟:


創建種子應用:

首先,我創建了一個種子應用程序在以下步驟中使用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,無論選擇哪條路線。

需要對上述代碼進行哪些特定更改,以便每條路徑在瀏覽器中打印titlebodyHTML的不同值?


@陰間大法師的建議:

每@陰間大法師的建議,我嘗試了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(); 
    } 
} 

還需要改變什麼?

回答

2

兩件事情你需要認識到:

  • 當角導航到使用相同的組件的新途徑,它不會重新初始化組件。因此,您的ngOnInit僅在組件第一次加載時運行。

  • ngOnChanges是不是當任何組件屬性更改時觸發。當數據綁定屬性(由@Input() someProp表示)由父組件更改時會觸發它。 See the docs。所以你的ngOnChanges也沒有被觸發。更新你的模型時的路線變化,但該組件沒有

一種方法是注入路由器,聽Router.events可觀察和反應路線改變有

app.component。 TS

import {NavigationEnd, Router} from '@angular/router'; 
import { Observable } from 'rxjs/Observable'; 
import { Subscription } from 'rxjs/Subscription'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/filter'; 
... 

routerSub:Subscription; 

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(); 
} 

順便說一句,這可能不是一個好主意,有解析爲同一組件的多個路由。考慮一個parameterized route來代替!

+0

在OP的哪個類中添加您建議的代碼?爲什麼不可能讓多個結果解析爲相同的內容?這個應用程序的目的是使多個搜索引擎友好的路線使用相同的模板。 – CodeMed

+0

@CodeMed該代碼旨在運行在'app.component.ts'中。我對搜索引擎優化知之甚少,所以我不能建議如何使一個Angular應用程序搜索引擎友好。但是,您正在使用多個路線來解決路線參數旨在解決的問題。我不知道'/ route1','/ route2'比'/ route/1','/ route/2'更好(最後參數) – BeetleJuice

+0

我剛剛添加了一個新的' AppComponent'和你的建議,並描述其餘的編譯錯誤。我還需要改變它嗎? – CodeMed

相關問題