如何将数据传递给angular度路由组件?
在我的一个Angular 2路由模板( FirstComponent )中,我有一个button
first.component.html
<div class="button" click="routeWithData()">Pass data and route</div>
我的目标是实现:
button点击 – >路由到另一个组件,同时保留数据,而不使用另一个组件作为指令。
这是我试过的…
1ST方法
在同一个视图中,我正在存储收集基于用户交互的相同数据。
first.component.ts
export class FirstComponent { constructor(private _router: Router) { } property1: number; property2: string; property3: TypeXY; // this a class, not a primitive type // here some class methods set the properties above // DOM events routeWithData(){ // here route } }
通常我会路由到SecondComponent
this._router.navigate(['SecondComponent']);
最终通过数据传递
this._router.navigate(['SecondComponent', {p1: this.property1, p2: property2 }]);
而带参数的链接的定义是
@RouteConfig([ // ... { path: '/SecondComponent/:p1:p2', name: 'SecondComponent', component: SecondComponent} )]
这种方法的问题是,我想我不能传递复杂的数据 (例如像property3的对象 )in-url;
第二种方法
另一种方法是在FirstComponent中包含SecondComponent作为指令 。
<SecondComponent [p3]="property3"></SecondComponent>
不过,我想路由到该组件,不包括它!
第三方法
我在这里看到的最可行的解决scheme是使用服务 (例如FirstComponentService)
- 将数据(_firstComponentService.storeData())存储在FirstComponent的routeWithData()中
- 在SecondComponent的 ngOnInit()中检索数据(_firstComponentService.retrieveData())
虽然这种方法似乎是完全可行的,但我想知道这是否是实现目标的最简单/最优雅的方法。
一般来说,我想知道是否遗漏了其他可能的方法来传递组件之间的数据,特别是在代码量较less的情况下
更新4.0.0
有关更多详细信息,请参阅Angular文档https://angular.io/guide/router#fetch-data-before-navigating
原版的
使用服务是一条路。 在路由参数中,您应该只传递想要反映在浏览器URL栏中的数据。
另见https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
RC.4附带的路由器重新引入了data
constructor(private route: ActivatedRoute) {}
const routes: RouterConfig = [ {path: '', redirectTo: '/heroes', pathMatch : 'full'}, {path : 'heroes', component : HeroDetailComponent, data : {some_data : 'some value'}} ];
class HeroDetailComponent { ngOnInit() { this.sub = this.route .data .subscribe(v => console.log(v)); } ngOnDestroy() { this.sub.unsubscribe(); } }
请参阅https://github.com/angular/angular/issues/9757#issuecomment-229847781中的Plunker
我认为,因为我们在angular 2中没有$ rootScopetypes的东西,就像在angular 1.x中一样。 我们可以在ngOnDestroy传递数据的同时使用angular度2的共享服务/类,在路由从ngOnInit函数的服务中获取数据之后:
在这里我使用DataService来分享英雄对象:
import { Hero } from './hero'; export class DataService { public hero: Hero; }
从第一个页面组件传递对象:
ngOnDestroy() { this.dataService.hero = this.hero; }
从第二个页面组件获取对象:
ngOnInit() { this.hero = this.dataService.hero; }
这是一个例子: plunker
第三种方法是在组件之间共享数据的最常见方式。 您可以在相关组件中注入要使用的项目服务。
import { Injectable } from '@angular/core'; import { Predicate } from '../interfaces' import * as _ from 'lodash'; @Injectable() export class ItemsService { constructor() { } removeItemFromArray<T>(array: Array<T>, item: any) { _.remove(array, function (current) { //console.log(current); return JSON.stringify(current) === JSON.stringify(item); }); } removeItems<T>(array: Array<T>, predicate: Predicate<T>) { _.remove(array, predicate); } setItem<T>(array: Array<T>, predicate: Predicate<T>, item: T) { var _oldItem = _.find(array, predicate); if(_oldItem){ var index = _.indexOf(array, _oldItem); array.splice(index, 1, item); } else { array.push(item); } } addItemToStart<T>(array: Array<T>, item: any) { array.splice(0, 0, item); } getPropertyValues<T, R>(array: Array<T>, property : string) : R { var result = _.map(array, property); return <R><any>result; } getSerialized<T>(arg: any): T { return <T>JSON.parse(JSON.stringify(arg)); } } export interface Predicate<T> { (item: T): boolean }