以角度将数据从一个组件传递到另一个组件

Posted

技术标签:

【中文标题】以角度将数据从一个组件传递到另一个组件【英文标题】:Pass data from one component to another in angular 【发布时间】:2019-08-03 04:06:12 【问题描述】:

我正在开发一个包含搜索功能的应用程序。

现在我在应用程序中有 2 个组件 1.导航栏 2. 搜索网格列表

Navbar 组件包含一个文本框,您可以在其中输入搜索查询并按 Enter,该组件将进行 api 调用并获取数据。 当数据返回时,我想将此数据填充到 SearchGridList 组件中的数组中。

我很难理解在 Angular 中的组件内传递数据,有人可以看看我的代码并指导我。

navbar.component.ts

import  Component, OnInit, Input, Output  from '@angular/core';
import DataService from '../../services/data.service';
import SearchResults from '../class/search.class';
import SearchGridListComponent from '../search-grid-list/search-grid-list.component';
import  EventEmitter  from '@angular/core';

@Component(
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
)
export class NavbarComponent implements OnInit 

  searchQuery : String;
  //searchResultList : Array<any> = [];

  constructor(private dataService :  DataService)  

  doSearch () : any
  
    this.dataService.doSQLSearch(this.searchQuery)
    .then ((data:any)=>
      for (var i =0; i<data.Results.length;i++)
        let searchObj = new SearchResults(data.Results[i]);
        //I want to push data into array from SearchGrid like this 
        resultGridList.push(searchObj);

      
    );
   

  ngOnInit() 
  

navbar.component.html

<mat-toolbar class="main-header">
  <a href="/">
  <img src="../../../assets/vms-header-logo.png" id= "header-logo">
  </a>
    <form class="search-box">
      <mat-form-field  class="search-box-full-width">
        <input id ="search-textbox" matInput placeholder="Enter a Barcode, DSID or any search term" name="Search" [(ngModel)]="searchQuery" (keyup.enter)="doSearch()" autocomplete="off">
      </mat-form-field>
    </form>
</mat-toolbar>

search-grid.component.ts

import  Component, OnInit, Input  from '@angular/core';
import NavbarComponent from '../navbar/navbar.component';

@Component(
  selector: 'app-search-grid-list',
  templateUrl: './search-grid-list.component.html',
  styleUrls: ['./search-grid-list.component.css'],
)
export class SearchGridListComponent implements OnInit 
  resultGridList : Array <any> = [];
  constructor()  

  ngOnInit() 
  


【问题讨论】:

包含网格和导航栏的父组件的html/js代码如何? 请更具体。 from this具体有什么不明白的? 请查看此链接angular.io/guide/… 如果组件是父子组件,则可以使用输入绑定如果不是,最好的解决方案是使用服务,因为链接正在解释 @KamilKiełczewski - 对 - 这将是第三个未提及的组件 - App 组件。 【参考方案1】:

您可以在DataService 中创建BehaviorSubject

private messageSource = new BehaviorSubject<string>('service');

你可以参考这个演示在组件之间传递数据。

https://stackblitz.com/edit/behavior-subject-2019

【讨论】:

是的 .. 我也可以推荐 BehaviourSubject。因此,例如,我将其用于身份验证状态.. 我写了一篇关于此的帖子:medium.com/@fransyozef/…【参考方案2】:

您需要在@Output事件之后添加到导航栏:

export class NavbarComponent implements OnInit 
   ...
   @Output() public found = new EventEmitter<any>();
   ...
   doSearch () : any
   
    this.dataService.doSQLSearch(this.searchQuery) .then ((data:any)=>
      for (var i =0; i<data.Results.length;i++)
        let searchObj = new SearchResults(data.Results[i]);

        this.found.emit(searchObj);  // !!!! here emit event
                                     // however emitting events in loop looks strange... better is to emit one evet

      
    );
   
   ...

好的,在您的网格组件中使用@Input 作为resultGridList 参数

export class SearchGridListComponent implements OnInit 

  @Input() public resultGridList : Array <any> = [];
  ...

好的,现在在你的 App 组件中按照以下方式加入这两个

应用模板html:

<app-navbar (found)="handleResults($event)"></app-navbar>

<app-search-grid-list [resultGridList]="data"></app-search-grid-list>

并且在 App ts 文件中:

data = [];
...

handleResults(searchObj) 
  this.data = searchObj

【讨论】:

这帮助我解决了我的问题。只是一个简单的问题,这是正确的方法吗?我知道我可以创建一个服务并注入它,但我不想创建只会在应用程序中使用一次的服务。 @KshitijAnilRangari 通常应用程序有 N 个服务(取决于 restfulapi、db-backend-domain 中的资源/请求),并且该组服务由 K 个组件使用,其中通常 K>N。我不知道您的域看起来如何。我的解决方案是标准方法,但是Hien 提出的解决方案也是有趣(并且更先进)的替代方案。 @KamilKiełczewski 如果我不想在导航栏中搜索其他组件怎么办?如果我们这样做 &lt;app-navbar (found)="handleResults($event)"&gt;&lt;/app-navbar&gt; ,则需要在每个组件中添加它。如果不是,它将抛出 NullInjector 错误。在这种情况下,解决方案是什么? @NoobCoder 这是一个单独的问题,您可以在 *** 上提问。但是我会使用一些带有全局事件的单例服务来完成它【参考方案3】:

@Input用于定义一个输入属性,实现component property binding。 @Inoput 装饰器用于将数据(属性绑定)从父组件传递到子组件。 组件属性应使用 @Input 装饰器进行注释,以充当输入属性。

【讨论】:

【参考方案4】:

也只需在search-grid 组件中注入dataService。服务是单例的,您可以跨组件共享它们。

在一个组件中:

dataService.test = "hello";

在另一个组件中:

console.log(dataService.test); // "hello"

这就是服务的用途。

【讨论】:

以上是关于以角度将数据从一个组件传递到另一个组件的主要内容,如果未能解决你的问题,请参考以下文章

以角度将数据从一个打字稿文件传递到另一个[重复]

将数组从一个组件传递到另一个组件的角度

角度传递数组到另一个(非子)组件

在没有导航或路由的角度 2 类型脚本中,将数据一个组件传递到另一个组件的所有可能性是啥?

将数据从一个组件传递到另一个 Angular 2

在 React 中将状态数据从一个组件传递到另一个组件