具有来自父组件的属性的 Angular 子组件

Posted

技术标签:

【中文标题】具有来自父组件的属性的 Angular 子组件【英文标题】:Angular children components with attributes from parent component 【发布时间】:2020-03-29 01:53:35 【问题描述】:

我正在尝试创建以下组件架构。 具有大模板的父组件,该模板是许多子组件的占位符。父组件负责从服务器获取数据。父模块还具有向子组件提供数据的服务。实际数据订阅在子组件中占有一席之地。 以下是一些相关代码: 通用子组件:

import  Component, OnDestroy, OnInit, ViewChild, ElementRef, AfterViewInit  from '@angular/core';
import  DataSvcService  from '../../dashboard/data-svc.service';

@Component(
 selector: 'app-generalstatistics',
 templateUrl: './generalstatistics.component.html',
 styleUrls: ['./generalstatistics.component.css']
)
export class GeneralstatisticsComponent implements OnInit, OnDestroy, AfterViewInit  
@ViewChild('generalstatistics', static: false) span: ElementRef;
subscription;
generalStatistics = new Array();

constructor(private dataSvc: DataSvcService) 

ngOnInit() 
  this.subscription = this.dataSvc.generalstatistics.subscribe(data => 
  this.generalStatistics = data;
 );

ngAfterViewInit() 
  console.log(this.span);

ngOnDestroy() 
  this.subscription.unsubscribe();


模板:generalstatistics.component.html

<span #generalstatistics></span>

父组件(实现模板):

<div class="card-body pb-0">
    <app-generalstatistics></app-generalstatistics>
</div>

父组件服务:'../../dashboard/data-svc.service'

import  BehaviorSubject, Subject, Observable  from 'rxjs';
import  Injectable  from '@angular/core';

@Injectable()
export class DataSvcService 

constructor()  
  public generalstatistics = new BehaviorSubject<Array<object>>([]);

public get generalStatistics(): Observable<Array<object>> 
  return this.generalstatistics.asObservable();


父组件数据请求:

this.http.get<any>(`$environment.apiUrl/api/
 home/`)
.subscribe((data: any) => 
  this.dataSvcService.generalstatistics.next(data);
);

我的想法是我希望将一般统计数据作为通用组件。实际的数据绑定应该发生在父组件中。我正在尝试在实现中添加类似的内容:

<app-generalstatistics **#someid**></app-generalstatistics>

所以我可以在 generalstatistics 组件代码中识别它并将数据分配给 span 元素。 但是当我检查 this.span.nativeElement 时,我没有看到任何来自实际实现的东西。

我的问题是如何在我的解决方案中将数据绑定到子组件?我应该改变整个架构吗?

谢谢

【问题讨论】:

我可以确认一下 - 您只希望您的父级的 generalStatistics 中的数据实际显示在您的子组件中吗? 是的,没错。 根据您对另一个答案的 cmets,您静态不知道您将拥有多少个子组件,这是否也正确?即,如果数据需要,您可能有一个子组件,或者您可能有多个。 嗯,我知道我将拥有多少个子组件。我想使用一个通用控件的原因是因为它们都是相同的,只是显示不同的数据。 【参考方案1】:

你试过了吗? 在您的父组件中,您可以像这样传递:

<app-generalstatistics [id]="someid" ></app-generalstatistics>

在您的 generalstatistics component.ts 中您可以通过这种方式接收:

@Input() id;

【讨论】:

这甚至无法编译:src/app/views/dashboard/dashboard.component.html(7,42) 中的错误:“DashboardComponent”类型上不存在属性“someData”。因为父组件对子组件一无所知。 您应该将 someData 或 someId 作为父组件中的类级别属性。 不,这不是我想要的。我想要的只是实现向子组件标识自己。 你能清楚地解释一下,'让实现来向子组件标识自己'是什么意思?据我了解,您只想将一些数据传递给子组件,而子组件必须根据传递的数据动态运行,对吗? 是的,你理解正确。为了将数据动态分配给子组件,我需要知道是什么实现了它。如果我在父组件中有两个子组件,我需要识别每个实例以分配正确的数据。【参考方案2】:

让我们假设您的服务正确地返回了您正在寻找的对象数组。然后,您需要做的就是将该数据绑定到您的子组件。

因此,在您的子组件中,它只会在 ts 文件中包含以下内容。

@Input() data: any; // You can replace "any" with an interface of the expected object

然后在你的父html文件中,如果你知道数据返回的顺序,就可以静态绑定数据,像这样:

<app-generalstatistics
[data]="this.generalStatistics[0]"
>

<app-generalstatistics
[data]="this.generalStatistics[1]"
>

或者如果您不确定数组中有多少对象,您可以简单地指定:

<app-generalstatistics *ngFor="let gS of generalStatistics"
[data]="gS"
>

使用上述任何策略,您都可以删除您的 ViewChild()、elementRef,因为您最终不会在您的 ts 文件中再次使用它。

【讨论】:

以上是关于具有来自父组件的属性的 Angular 子组件的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 @Input - 如何从父组件绑定子组件的 ID 属性?

Angular 2父组件丢失来自子组件的输入绑定

在父组件中显示来自子组件的按钮的结果 - Angular

具有多个子组件实例的Angular2父组件

angular 5 从父组件设置子组件属性

如何在 Angular 中显示具有自己路由的父组件内的特定子组件?