【问题标题】:How to pass type from parent to child component?如何将类型从父组件传递给子组件?
【发布时间】:2020-11-05 23:24:03
【问题描述】:

我正在尝试创建一个将使用 MatTable 组件的抽象表格组件。抽象表将用作子元素,我想将自定义接口(其行为类似于类型)从父元素传递给该子元素。

到目前为止,我决定通过这样的一个对象传递数据和表设置:

//inside the parent component

<app-abstract-table [tableProperties]="tableProperties"></app-abstract-table>

tableProperties对象是基于如下接口创建的:

export interface TableProperties {
    columnsWithCaptions?: any[];
    dataSource?: any[];
}

app-abstract-table 中,我有一个包含表格数据的字段:
dataSource: MatTableDataSource&lt;Fruit&gt; = new MatTableDataSource&lt;Fruit&gt;();
它的泛型类型是Fruit

我想以某种方式从父级传递这种类型,这样整个抽象表组件将完全可重用。这甚至可以实现吗?或者我应该把any 作为一个泛型并忘记这个问题?

【问题讨论】:

  • 您可以创建单独的文件,并为其添加接口。然后在您的两个组件中导入此文件。这样,您就不需要将接口作为输入属性传递。
  • @GaurangDhorda 你能描述更多如何做到这一点吗?在我看来,我没有得到它。
  • 所以,我猜“任何”都是正确的选择
  • @digitalis 不,它永远不会。请改用unknown :)

标签: angular typescript generics angular-material


【解决方案1】:

我今天遇到了类似的需求,但我没有找到很多资源,所以我尝试了 C# 泛型的方式,它成功了。所以我在下面发布了一个小例子的发现。

因此,为了实现这一点,我们需要像下面这样将泛型类型持有者添加到子组件中,以便我们可以从父组件传递类型:


    import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
    
    @Component({
      selector: 'app-child',
      templateUrl: './child.component.html',
      styleUrls: ['./child.component.css']
    })
    export class ChildComponent<TType> {
      @Input() genericType?: TType;
      @Output() selected: EventEmitter<TType> = new EventEmitter<TType>();
    
      onClick(): void {
        if (this.genericType) {
          this.selected.emit(this.genericType);
        }
      }
    }

然后从父级,我们需要传递所需的对象类型。在这里,我传递了示例的数字和字符串。


    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-parent',
      templateUrl: './parent.component.html',
      styleUrls: ['./parent.component.css']
    })
    export class ParentComponent implements OnInit {
      genericTypeNumber: number= 2022;
      genericTypeString: string= "Hello World!!";
      constructor() { }
    
      ngOnInit(): void {
      }
    
      onSelectedNumber(numberType: number){
        console.log(numberType);
      }
    
      onSelectedString(stringType: string){
        console.log(stringType);
      }
    
    }

在父 HTML 中,将属性正常分配给子组件:


    <app-child [genericType]="genericTypeNumber" (selected)="onSelectedNumber($event)"></app-child>
    <app-child [genericType]="genericTypeString" (selected)="onSelectedString($event)"></app-child>

这也将确保类型安全。 如果您需要在现有接口中使用泛型类型,则可以执行以下操作。


    export interface IGenericModel<TCustomType> {
        id: number;
        customValue: TCustomType;
    }

子组件会是这样的:


    import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
    import { IGenericModel } from './genericModel';
    
    @Component({
      selector: 'app-child',
      templateUrl: './child.component.html',
      styleUrls: ['./child.component.css']
    })
    export class ChildComponent<TType> {
      @Input() genericType?: IGenericModel<TType>;
      @Output() selected: EventEmitter<IGenericModel<TType>> = new EventEmitter<IGenericModel<TType>>();
    
      onClick(): void {
        if (this.genericType) {
          this.selected.emit(this.genericType);
        }
      }
    }

【讨论】:

    【解决方案2】:

    您的表属性可以定义为:

    export interface TableProperties<T> {
      columnWithCaptions?: any[];
      dataSource?: T[];
    }
    

    【讨论】:

    猜你喜欢
    • 2020-03-30
    • 1970-01-01
    • 2022-11-24
    • 2020-02-04
    • 2020-11-01
    • 2017-08-16
    • 2019-02-17
    • 2020-08-21
    • 1970-01-01
    相关资源
    最近更新 更多