使用Angular 2路由器将不同的值传递给同一个组件

时间:2017-07-11 00:17:35

标签: javascript angular typescript

  

以下代码针对三种不同的路线提供相同的组件AppComponent,包括//route2/route3

     

问题是,title的{​​{1}}和bodyHTML属性在选择不同路由时不会更改值。

     

需要对下面的代码进行哪些具体更改,以便当用户选择每条不同的路线时,应用会为AppComponenttitle提供不同的值?< / strong>

     

以下是在几分钟内 重现问题的步骤


创建种子应用程序:

首先,我在以下步骤中使用Angular-CLI创建了种子应用程序:

bodyHTML


只更改4个文件:

接下来,我只更改了4个文件,如下所示:

我添加了cd C:\projects\angular-cli ng new routes-share-component cd C:\projects\angular-cli\routes-share-component ng serve 以下内容:

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 Titletitle打印不同的值?


@ BeetleJuice的建议:

根据@ BeetleJuice的建议,我尝试了以下新版本的bodyHTML,但它显示了AppComponent行和routerSub:Subscription行的编译错误。

this.routerSub = this.router.events.filter(....)

还需要改变什么?

1 个答案:

答案 0 :(得分:2)

您需要认识到的两件事:

  • 当Angular导航到使用相同组件的新路由时,它不会重新初始化组件。因此,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