具有来自父组件的属性的 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 子组件的主要内容,如果未能解决你的问题,请参考以下文章