首页 > 解决方案 > Angular 8:将数据传递给路由器

问题描述

我有一个包含产品列表的页面,我想将产品 id 传递给 product/:id 路由器(我不想从路由器 url 解析它)。我有什么选择?我可以有类似Input()路由器组件的东西吗?

标签: angularangular-routing

解决方案


让我先解决这个问题!

您有一个项目列表,当您单击一个时,您需要重定向到显示参考项目 ID 的详细信息的一般路线?您正在寻找一种将项目 ID 传递给子组件而不将其作为路由参数传递的方法?

这基本上是在组件之间共享数据。有 4 种方法可以做到这一点。

父母对孩子:通过共享数据Input

这可能是最常见和最直接的数据共享方法。它通过使用@Input()装饰器来允许通过模板传递数据。

孩子对父母:通过共享数据ViewChild

ViewChild允许将一个组件注入到另一个组件中,从而使父组件可以访问其属性和功能。然而,一个警告是,在视图初始化之前,孩子将不可用。这意味着我们需要实现AfterViewInit生命周期钩子来接收来自孩子的数据。

孩子对父母:通过Output()和共享数据EventEmitter

当您想要共享发生在按钮单击、表单条目和其他用户事件等事件上的数据更改时,这种方法是理想的选择。

在父级中,您可以创建一个函数来接收消息并将其设置为等于消息变量。

在孩子中,messageEvent使用 Output 装饰器声明一个变量,并将其设置为新的事件发射器。然后创建一个名为的函数,该函数sendMessage使用您要发送的消息调用此事件的发射。最后,创建一个按钮来触发此功能。

父组件现在可以订阅messageEvent子组件输出的 this,然后在该事件发生时运行接收消息函数。

不相关的组件:与服务共享数据(推荐)

在缺少直接连接的组件之间传递数据时,例如兄弟姐妹、孙辈等,您应该使用共享服务。当您拥有应该始终同步的数据时,我发现 RxJSBehaviorSubject在这种情况下非常有用。

以下是最后一种方法的示例!

共享服务.ts

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class DataService {

  private messageSource = new BehaviorSubject('default message');
  currentMessage = this.messageSource.asObservable();

  constructor() { }

  changeMessage(message: string) {
    this.messageSource.next(message)
  }

}

父组件.ts

import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";

@Component({
  selector: 'app-parent',
  template: `
    {{message}}
  `,
  styleUrls: ['./sibling.component.css']
})
export class ParentComponent implements OnInit {

  message:string;

  constructor(private data: DataService) { }

  ngOnInit() {
    //subscribing to the updated data set
    this.data.currentMessage.subscribe(message => this.message = message)
  }

}

兄弟组件.ts

import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";

@Component({
  selector: 'app-sibling',
  template: `
    {{message}}
    <button (click)="newMessage()">New Message</button>
  `,
  styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit {

  message:string;

  constructor(private data: DataService) { }

  ngOnInit() {
    this.data.currentMessage.subscribe(message => this.message = message)
  }

  newMessage() {
    // triggering the shared service method
    this.data.changeMessage("Hello from Sibling")
  }

}

我希望这种方法有效。

祝你好运!


推荐阅读