【问题标题】:How to pass data between two components in Angular 2如何在Angular 2中的两个组件之间传递数据
【发布时间】:2017-01-12 12:34:33
【问题描述】:

我正在寻找将数据传递给另一个组件并类似地访问其他组件中另一个组件的方法的解决方案(两者都是并行组件)。

例如,我有两个组件 home.tsmap.ts。 我将一些数据输入map.ts,并需要将其传递给home.ts,反之亦然。

【问题讨论】:

标签: angular components shared-data


【解决方案1】:

在 Angular 中,您可以使用 @Input 在组件之间共享数据。 首先你应该从@angular/core 导入输入:

import { input } form '@angular/core';

然后在组件类中,在要传递的变量前添加@input:

@input() variableName;

【讨论】:

  • 这取决于组件之间的关系。当我们有父子关系时,我们使用@input 装饰器。当组件不相关时,我们使用最近挽救了我生命的共享服务方法:D。
【解决方案2】:

您可以使用服务传输数据。

在您切换组件时创建一个保存数据的服务。下面是一个例子。

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

@Injectable()
export class TransfereService {

  constructor(
    private router:Router,
    private companyServiceService:CompanyServiceService
  ) { }

  private data;

  setData(data){
    this.data = data;
  }

  getData(){
    let temp = this.data;
    this.clearData();
    return temp;
  }

  clearData(){
    this.data = undefined;
  }

}

现在考虑 2 个组件 Sender 和 Reciever。

发送者代码:此代码将数据设置到服务并导航到接收者。

import { Router } from '@angular/router';
import { TransfereService } from './services/transfer.service';

export class SenderComponent implements OnInit {         
  constructor(
    private transfereService:TransfereService,
    private router:Router) {}

  somefunction(data){
   this.transfereService.setData(data);
   this.router.navigateByUrl('/reciever');//as per router
 }
}

接收方代码:此代码从服务中获取数据并清除数据。

import { Router } from '@angular/router';
import { TransfereService } from './services/transfer.service';

export class RecieverComponent implements OnInit {  
 data = this.transfereService.getData();       
 constructor(
   private transfereService:TransfereService,
   private router:Router) {
      if(this.data){
        // do whatever needed
      }
      else{
        this.router.navigateByUrl('/sender');
      }
   }
}

您也应该查看Fireship Demo。很有帮助。

【讨论】:

  • 这应该是公认的答案。大多数其他答案都涉及与子组件共享的父组件;这涉及共享数据的对等组件。
  • 这应该是公认的答案。这也是其中一个如此明显但甚至没有意识到的。而且它非常酷,因为您注入的任何组件都将拥有数据(感谢单例实例化),而无需围绕 Angular 输入和输出做其他复杂的事情
  • 非常感谢,阿比吉特。我花了很多时间尝试。希望我早点看到你的答案。
  • 这是最好的答案!解释的很好,比官方文档还要好。谢谢!
  • 我们可以使用angular resolve 共享数据吗?
【解决方案3】:

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

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

子级到父级:通过 Output() 和 EventEmitter 共享数据 共享数据的另一种方法是从子级发出数据,父级可以列出这些数据。当您想要共享发生在按钮单击、表单整体和其他用户事件等事件上的数据更改时,这种方法是理想的选择。

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

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

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

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

您也可以使用常规的 RxJS 主题通过服务共享数据,但这就是我更喜欢 BehaviorSubject 的原因。

它总是会在订阅时返回当前值 - 无需调用 onnext 它有一个 getValue() 函数来提取最后一个值作为原始数据。 它确保组件始终接收最新数据。 在服务中,我们创建一个私有的 BehaviorSubject 来保存消息的当前值。我们定义了一个 currentMessage 变量,将这个数据流作为一个 observable 来处理,供组件使用。最后,我们创建函数,调用 BehaviorSubject 上的 next 来更改其值。

父组件、子组件和兄弟组件都接受相同的处理。我们在构造函数中注入 DataService,然后订阅 currentMessage observable 并将其值设置为等于 message 变量。

现在,如果我们在其中任何一个组件中创建一个函数来更改消息的值。当这个函数被执行时,新数据会自动广播到所有其他组件。

参考:https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/

【讨论】:

    【解决方案4】:

    使用 sessionStorage,在要设置数据的角度将其写入

    sessionStorage.setItem("key","value");
    

    如果你想存储你的对象然后写成

    sessionStorage.setItem("key", JSON.stringify(obj));
    

    然后是您想要正确获取值的组件 sessionStorage.getItem("key") 或整个对象 JSON.parse(sessonStorage.getKey("key");

    【讨论】:

    • 毫无疑问,这种方法会奏效,但数据仍然可见并且容易受到更改。如果有人更改 JSON 结构,应用程序会崩溃。
    【解决方案5】:

    在 Angular 4 中,使用 @Input 在父子之间共享一个对象。在这里,对 megmor(在父级中)或 radfal(在子级中)的更改将反映在另一个中。

    父 html:

    <div>   
      <zoptil [radfal]="megmor"></zoptil>
      {{megmor.pergal}}
    </div>
    

    父 ts:

    let megmor = new Kreven();
    this.megmor.pergal = "warbar";
    

    子 html:

    <div>
      <h2>{{radfal.pergal}}</h2>
      <label>Peragl: </label>
      <input [(ngModel)]="radfal.pergal" />
    </div>
    

    儿童 ts:

    @Input() radfal: Kreven;
    

    【讨论】:

      【解决方案6】:

      在组件之间传递数据是一个双向过程。在您的情况下,假设home.ts 包含一个名为data 的对象。

      1.在 home.component.html 中使用 &lt;map-component&gt;&lt;/map-component&gt; 的地方,将其替换为 &lt;map-component [data]="data"&gt;&lt;/map-component&gt;

      2.在map.ts文件中,添加如下输入:

      @Input() data: string;
      
      1. 现在您可以在代码中使用它,例如 &lt;p&gt;{{data.title}}&lt;/p&gt;

      希望对你有帮助!

      【讨论】:

      【解决方案7】:

      在 Angular2 中,您可以通过在 html 中传递对象来在两个组件之间进行通信。

      例子

      home.html:

      ...
      <map_selector [ObjectInMap]="ObjectInHome" ></map_selector>
      ...
      

      【讨论】:

        【解决方案8】:

        您可以使用 angular 2 Inputs 将数据传递给组件。例如,在您的子类中,使用 angular 2 @Input 装饰器创建一个输入变量。

        import {Component, Input} from 'angular2/core';
        
        @Component({
          selector: 'child',
          styles: [`
          `],
          template: `
          `
        })
        export class ChildComponent {
          @Input() valueToPass = 0;
        }
        

        在您的父组件中(即您在其中调用您的子组件,按如下方式传递您的参数:

        <child [valueToPass] = "value"></child>
        

        我建议您阅读这篇关于在组件之间传递和接收参数的文章 (https://toddmotto.com/passing-data-angular-2-components-input)。

        【讨论】:

          猜你喜欢
          • 2018-02-22
          • 2016-03-24
          • 2020-10-10
          • 2017-08-12
          • 1970-01-01
          • 2016-04-29
          • 2017-03-31
          • 1970-01-01
          相关资源
          最近更新 更多