在我的Angular 2路由模板之一(FirstComponent)中,我有一个按钮

first.component.html

<div class="button" click="routeWithData()">Pass data and route</div>

我的目标是:

按钮点击->路由到另一个组件,同时保留数据,而不使用另一个组件作为指令。

这是我试过的…

1号的方法

在同一个视图中,我根据用户交互存储收集相同的数据。

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
    }
}

通常我会通过

 this._router.navigate(['SecondComponent']);

最终传递数据

 this._router.navigate(['SecondComponent', {p1: this.property1, p2: property2 }]);

而带有参数的链接的定义将是

@RouteConfig([
      // ...
      { path: '/SecondComponent/:p1:p2', name: 'SecondComponent', component: SecondComponent} 
)]

这种方法的问题是,我猜我不能在url中传递复杂的数据(例如property3这样的对象);

2方法

另一种方法是在FirstComponent中包含SecondComponent作为指令。

  <SecondComponent [p3]="property3"></SecondComponent>

然而,我想路由到该组件,不包括它!

第三个方法

我在这里看到的最可行的解决方案是使用一个服务(例如FirstComponentService)来

将数据(_firstComponentService.storeData())存储在FirstComponent的routeWithData()上 在SecondComponent的ngOnInit()中检索数据(_firstComponentService.retrieveData())

虽然这种方法似乎完全可行,但我想知道这是否是实现目标的最简单/最优雅的方法。

一般来说,我想知道我是否错过了在组件之间传递数据的其他潜在方法,特别是在代码量可能较少的情况下


当前回答

更新4.0.0

更多细节请参见Angular Angular Router -在导航前获取数据。

原始

使用服务是正确的选择。在路由参数中,您应该只传递希望在浏览器URL栏中反映的数据。

参见Angular Cookbook组件通信-双向服务。

RC.4附带的路由器重新引入了数据

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

参见Plunker。

其他回答

使用JSON传递

  <a routerLink = "/link"
   [queryParams] = "{parameterName: objectToPass| json }">
         sample Link                   
  </a>

我查看了本页中的每个解决方案(并尝试了一些),但我不相信我们必须实现一种hack式的方式来实现路由之间的数据传输。

简单历史的另一个问题。状态是指,如果您在状态对象中传递特定类的实例,在接收它时它将不是实例。但它将是一个简单的JavaScript对象。

所以在我的Angular v10 (Ionic v5)应用中,我这样做了

this.router.navigateByUrl('/authenticate/username', {
    state: {user: new User(), foo: 'bar'}
});

在导航组件('/authenticate/username')中,在ngOnInit()方法中,我用this.router.getCurrentNavigation().extras.state-打印了数据

ngOnInit() {
    console.log('>>authenticate-username:41:',
        this.router.getCurrentNavigation().extras.state);
}

我得到了想要的数据

说你有

component1.ts component1.html

您希望将数据传递给component2.ts。

in component1.ts is a variable with data say //component1.ts item={name:"Nelson", bankAccount:"1 million dollars"} //component1.html //the line routerLink="/meter-readings/{{item.meterReadingId}}" has nothing to //do with this , replace that with the url you are navigating to <a mat-button [queryParams]="{ params: item | json}" routerLink="/meter-readings/{{item.meterReadingId}}" routerLinkActive="router-link-active"> View </a> //component2.ts import { ActivatedRoute} from "@angular/router"; import 'rxjs/add/operator/filter'; /*class name etc and class boiler plate */ data:any //will hold our final object that we passed constructor( private route: ActivatedRoute, ) {} ngOnInit() { this.route.queryParams .filter(params => params.reading) .subscribe(params => { console.log(params); // DATA WILL BE A JSON STRING- WE PARSE TO GET BACK OUR //OBJECT this.data = JSON.parse(params.item) ; console.log(this.data,'PASSED DATA'); //Gives {name:"Nelson", bankAccount:"1 //million dollars"} }); }

ActiveRoute的解决方案(如果你想通过路由传递对象-使用JSON.stringfy/JSON.parse):

发送前准备对象:

export class AdminUserListComponent {

  users : User[];

  constructor( private router : Router) { }

  modifyUser(i) {

    let navigationExtras: NavigationExtras = {
      queryParams: {
          "user": JSON.stringify(this.users[i])
      }
    };

    this.router.navigate(["admin/user/edit"],  navigationExtras);
  }

}

在目标组件中接收对象:

export class AdminUserEditComponent  {

  userWithRole: UserWithRole;      

  constructor( private route: ActivatedRoute) {}

  ngOnInit(): void {
    super.ngOnInit();

      this.route.queryParams.subscribe(params => {
        this.userWithRole.user = JSON.parse(params["user"]);
      });
  }

}

Angular 7.2.0引入了在路由组件之间导航时传递数据的新方法:

@Component({
  template: `<a (click)="navigateWithState()">Go</a>`,
})
export class AppComponent  {
  constructor(public router: Router) {}
  navigateWithState() {
    this.router.navigateByUrl('/123', { state: { hello: 'world' } });
  }
}

Or:

@Component({
  selector: 'my-app',
  template: `
  <a routerLink="/details" [state]="{ hello: 'world' }">Go</a>`,
})
export class AppComponent  {}

要读取状态,你可以在导航结束后访问window.history.state属性:

export class PageComponent implements OnInit {
  state$: Observable<object>;

  constructor(public activatedRoute: ActivatedRoute) {}

  ngOnInit() {
    this.state$ = this.activatedRoute.paramMap
      .pipe(map(() => window.history.state))
  }
}