Javascript 使用Angular 2 router将不同的值传递给同一组件
以下代码为同一组件Javascript 使用Angular 2 router将不同的值传递给同一组件,javascript,angular,typescript,Javascript,Angular,Typescript,以下代码为同一组件AppComponent提供三种不同的路由,包括/、/route2和/route3 import { Component, OnInit, OnChanges } from '@angular/core'; import { NavigationEnd, Router, ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; import 'rxjs
AppComponent
提供三种不同的路由,包括/
、/route2
和/route3
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();
}
}
问题在于AppComponent
的title
和bodyHTML
属性在选择不同的路由时不会更改值
需要对下面的代码进行哪些具体更改,以便当用户选择每个不同路线时,应用程序将为标题
和正文HTML
提供不同的值?
以下是几分钟内在任何计算机上重现问题的步骤:
创建种子应用程序:
首先,我在以下步骤中使用Angular CLI创建了一个seed应用程序:
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);
}
}
<div style="text-align:left">
<h1>{{title}}</h1>
<p>{{bodyHTML}}</p>
</div>
类似地,app.component.html
被简化为以下内容:
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);
}
}
<div style="text-align:left">
<h1>{{title}}</h1>
<p>{{bodyHTML}}</p>
</div>
请注意,ngOnInit()
块在控制台中打印,但ngOnChanges()
块不打印。这意味着无论选择哪条路线,标题始终为主页标题
需要对上述代码进行哪些具体更改,以便每条路线在浏览器中为标题和正文HTML
打印不同的值?
@belletJuice的建议:
根据@甲壳虫果汁的建议,我尝试了以下新版本的
AppComponent
,但它在RouterSubscription
行和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();
}
}
还有什么需要改变的吗?你需要意识到两件事:
- 当Angular导航到使用相同组件的新路由时,它不会重新初始化该组件。因此,您的
仅在第一次加载组件时运行ngOnInit
- 当任何组件属性发生更改时,不会触发ngOnChanges。当父组件更改数据绑定属性(如
所示)时,会触发该属性。因此,您的@Input()someProp
也不会被触发ngOnChanges
路由器。可观察到的事件
并对那里的路由改变作出反应
应用程序组件.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();
}
顺便说一句,让多条路由解析到同一个组件可能不是一个好主意。考虑换一个吧! 在OP的哪个类中添加您建议的代码?为什么将多个结果解析为同一内容不是一个好主意?此应用程序的目的是使多个搜索引擎友好的路由使用相同的模板。@CodeMed此代码将在
app.component.ts
中运行。我对搜索引擎优化知之甚少,所以我不能建议如何使一个有角度的应用程序对搜索引擎优化友好。但是,您正在使用多个路由来解决路由参数旨在解决的问题。我不知道拥有/route1
,/route2
比/route/1
,/route/2
(最后的参数)对搜索引擎优化有什么好处,我只是添加了一份新的应用组件的副本,并说明了剩余的编译错误。我还需要更改哪些内容?@CodeMed当您请求帮助时,请复制错误消息(如果适用)。您是否从'rxjs/Subscription'导入{Subscription}
?从'rxjs/Subscription添加导入{Subscription}消除了第一个编译错误,但是过滤器(…)
行仍然抛出[ts]属性'filter',在类型'observeable'上不存在。