Angular 8:将数据传递给路由器 [英] Angular 8: pass a data to a router

查看:25
本文介绍了Angular 8:将数据传递给路由器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含产品列表的页面,我想将产品 ID 传递给 product/:id 路由器(我不想从路由器 url 解析它).我有哪些选择?我可以将 Input() 之类的东西添加到路由器组件中吗?

解决方案

让我先解决这个问题!

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

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

父对子:通过输入

共享数据

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

子级到父级:通过 ViewChild

共享数据

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

子级到父级:通过 Output()EventEmitter

共享数据

当您想要共享发生在按钮点击、表单条目和其他用户事件等事件中的数据更改时,这种方法非常理想.

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

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

父组件现在可以订阅子组件输出的这个messageEvent,然后每当这个事件发生时运行接收消息函数.

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

在缺乏直接连接的组件(例如兄弟、孙子等)之间传递数据时,您应该共享服务.当您的数据应该始终保持同步时,我发现 RxJS BehaviorSubject 在这种情况下非常有用.

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

<块引用>

共享服务.ts

import { Injectable } from '@angular/core';从'rxjs'导入{BehaviorSubject};@Injectable()导出类数据服务{private messageSource = new BehaviorSubject('默认消息');currentMessage = this.messageSource.asObservable();构造函数(){}更改消息(消息:字符串){this.messageSource.next(消息)}}

<小时><块引用>

parent.component.ts

import { Component, OnInit } from '@angular/core';从../data.service"导入{数据服务};@成分({选择器:'app-parent',模板:`{{信息}}`,styleUrls: ['./sibling.component.css']})导出类 ParentComponent 实现 OnInit {消息:字符串;构造函数(私有数据:DataService){}ngOnInit() {//订阅更新的数据集this.data.currentMessage.subscribe(message => this.message = message)}}

<小时><块引用>

sibling.component.ts

import { Component, OnInit } from '@angular/core';从../data.service"导入{数据服务};@成分({选择器:'app-sibling',模板:`{{信息}}<button (click)="newMessage()">新消息</button>`,styleUrls: ['./sibling.component.css']})导出类 SiblingComponent 实现 OnInit {消息:字符串;构造函数(私有数据:DataService){}ngOnInit() {this.data.currentMessage.subscribe(message => this.message = message)}新消息() {//触发共享服务方法this.data.changeMes​​sage("兄弟你好")}}

我希望这种方法有效.

祝你好运!

I have page with a list of products, and I want to pass product id to a product/:id router (I don't want to parse it from router url). What options do I have? Can I have something like Input() to a router component?

解决方案

Let me get this right first!

You have a list of items and when you click on one, you need to redirect to a general route that displays the details in reference to the item id? You are looking for a way to pass the item id to the child component without passing it as a route parameter?

This is basically sharing data among components. There are 4 ways of doing that.

Parent to Child: Sharing Data via Input

This is probably the most common and straightforward method of sharing data. It works by using the @Input() decorator to allow data to be passed via the template.

Child to Parent: Sharing Data via ViewChild

ViewChild allows one component to be injected into another, giving the parent access to its attributes and functions. One caveat, however, is that the child won’t be available until after the view has been initialized. This means we need to implement the AfterViewInit lifecycle hook to receive the data from the child.

Child to Parent: Sharing Data via Output() and EventEmitter

This approach is ideal when you want to share data changes that occur on things like button clicks, form entries, and other user events.

In the parent, you can create a function to receive the message and set it equal to the message variable.

In the child, declare a messageEvent variable with the Output decorator and set it equal to a new event emitter. Then create a function named sendMessage that calls emit on this event with the message you want to send. Lastly, create a button to trigger this function.

The parent can now subscribe to this messageEvent that’s outputted by the child component, then run the receive message function whenever this event occurs.

Unrelated Components: Sharing Data with a Service (Recommended)

When passing data between components that lack a direct connection, such as siblings, grandchildren, etc, you should you a shared service. When you have data that should always be in sync, I find the RxJS BehaviorSubject very useful in this situation.

following is an example on the last approach!

shared-service.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)
  }

}


parent.component.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)
  }

}


sibling.component.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")
  }

}

I hope this approach works.

Good Luck!

这篇关于Angular 8:将数据传递给路由器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆