包装或扩展 angular-material 组件,允许将未知属性传递给子组件
Posted
技术标签:
【中文标题】包装或扩展 angular-material 组件,允许将未知属性传递给子组件【英文标题】:Wrap or extend angular-material component allowing pass-through of unknown attributes to child component 【发布时间】:2018-10-24 06:24:09 【问题描述】:我们正在使用 Angular 5 和材料设计,并使用各种功能的辅助方法创建我们自己的组件(即为mat-table
生成动态列)。
我想要一种将未知属性从父组件传递到子组件的方法。这在 React 中很容易,例如:
应用类渲染
<MyDatatable knownVar="1" otherKnownVar="2" unknownButKnownToChildVar="3" />
MyDataTable 渲染
<MatComponent ...this.props />
这样,如果MatComponent
更新了它所接受的属性,MyDataTable
就不必更新了。我查看了 @Input
装饰器,但这似乎并不能促进未知变量。
我想到的一个解决方案是只传入一个对象并通过@Input
说明该对象,但我不喜欢这样,因为我希望 angular-material 组件文档能够准确地反映开发人员应该如何正在使用 my MyDataTable
组件。
我的问题的简短版本:如何在 Angular 5 中将未说明的属性级数据传递给子组件?
【问题讨论】:
这在 Angular 中不存在,也不适用于 AoT。 如果您不想在数据发生变化时更改子组件,那么您肯定必须知道提供的是哪种数据。就像一个人组件将接收一个人作为输入。不过,您可以提供尽可能多的输入。因此,您可以定义所有已知的输入,并定义一个额外的输入来执行您在解决方案中描述的操作。 未知变量不能是对象类型,以便将来它可以包含对象属性形式所需的属性吗? 技术上是的,这就是我在问题的建议解决方案部分中所涵盖的内容。但是,这不会让您在任何名称的组件上提供属性。如果没有在MyAngComponent
类中专门为unknownAttribute
提供@Input
选择器,<MyAngComponent unknownAttribute="1">
将无法传递给子组件
一年后,你能解决这个问题吗?
【参考方案1】:
<div class="example-container mat-elevation-z8">
<table mat-table #table [dataSource]="dataSource">
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" -->
<!-- Column -->
<ng-container matColumnDef="column">
<th mat-header-cell *matHeaderCellDef> column </th>
<td mat-cell *matCellDef="let element"> element.symbol </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
Sample.html
只需传递可能来自父组件或子组件的数据源对象。
数据源 = 数据;
希望你明白我的意思,或者你需要一些不同的东西。根据您的问题,动态数据插入到您的表必须绑定到控制器部分。就角度而言,如果您的数据源模型由子组件和父组件更新。它会在更新发生时呈现数据。
如果可能,显示您的父子组件数据的代码? 谢谢
【讨论】:
这只是一个例子。问题是关于通过父组件未知但子组件知道 的属性发送数据。 目前在 Angular 中没有任何方法可以做到这一点。至少我知道。您可以像上面提到的那样执行一些变通方法,或者使用服务为您的组件提供您想要的任何数据。但是 Angular 不会让你将未知属性传递给组件。【参考方案2】:我能想到的使用 Angular 提供的 Input 装饰器做你想做的事情的一种方法是将 JS 对象 (any) 传递到组件输入中,并根据属性执行所需的代码。示例:
my-component.component.ts
import Component, OnInit, Input from '@angular/core';
@Component(
selector: 'my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
)
export class MyComponentComponent implements OnInit
@Input() data: any;
constructor()
ngOnInit()
app.component.html
<my-component [data]="data: 2, extraData: 3"></my-component>
在这种情况下,您可以在输入数据中添加 n* 个属性。没有将未知数量的属性传递给组件的任何实现。
您还可以做的另一件很酷的事情是在您的组件内部,您实际上可以有一些默认值,并且还可以期待更多。就像这里的例子:
app.component.html
<my-component [data]="name: 'John', surname: 'Doe'"></my-component>
my-component.component.ts
import Component, OnInit, Input from '@angular/core';
@Component(
selector: 'my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
)
export class MyComponentComponent implements OnInit
@Input() data: any;
constructor()
ngOnInit()
this.data =
name: "John",
surname: "Doe",
origin: "UK",
...this.data
my-component.component.html
<div *ngIf="data.phone">
Phone Number: data.phone
</div>
或者甚至制作某种 Object.keys(this.data) 并遍历数据属性并打印正确的 html。这样,您可以为已知属性设置一些默认值,甚至可以期待更多未知属性。
希望对我有所帮助。
【讨论】:
这是我提出的解决方案的一个很好的实现,但是我想我的问题的真正答案是你(和其他评论者)在你说:“没有任何实现将未知数量的属性传递给组件。”以上是关于包装或扩展 angular-material 组件,允许将未知属性传递给子组件的主要内容,如果未能解决你的问题,请参考以下文章
如何从 angular-material2 对话框与其父级进行通信
扩展 Kendo Angular 2 UI 组件并创建我们自己的具有所有 Kendo 组件功能的组件包装器
我是不是需要(或应该)将我所有的 Vue 组件包装在一个包装器组件中?