在 Angular 2 个子组件之间使用 @input 和 @output
Using @input and @output between Angular 2 child components
我有一个 ng-table
,它是我主页的子组件。单击一行时,它会使用 EventEmitter
通过 onCellClick
发送该行中的信息。我正在尝试将此信息发送到另一个子组件。这恰好是一个按钮,它是 Bootstrap 4 模式的子级,当单击主页上的按钮时弹出。只是在接收和处理该信息时遇到问题。
HTML 子组件 table:
<ng-table [config]="config"
(tableChanged)="onChangeTable(config)"
(cellClicked)="onCellClick($event)"
[rows]="rows" [columns]="columns">
</ng-table>
HTML 对于子组件(这出现在主页的 HTML):
<app-datatable (row)="received($event)"></app-datatable>
用于获取和发送行数据的 Typescript(this.row
是 EvenEmitter。data.row
是被点击的实际行):
@Output() row: EventEmitter<any> = new EventEmitter<any>();
public onCellClick(data: any): any {
let d = data.row.tDataPoint;
let i = data.row.tICCP;
let s = data.row.tStartDate;
let e = data.row.tEndDate;
let toSend:DataTable = new DataTable(d, i, s, e);
this.row.emit(toSend);
}
HTML 对于作为 Bootstrap 4 模态的子组件的按钮:
<button type="submit" class="btn" data-dismiss="modal" (click)="onClick($event)">Delete</button>
按钮子组件的打字稿:
selector: 'deletebutton'
@Input() receivedRow:DataTable;
onClick(message:DataTable){
this.sender.emit('This is from On Click Deletebutton');
console.log("On Click Deletebutton");
console.log(this.receivedRow);
for (let entry in DPS){
if (DPS[entry].tDataPoint===message.tDataPoint){
DPS.splice(parseInt(entry),1);
}
}
}
按钮子组件的 HTML(这出现在模态的 HTML 中)。这实际上应该从单击的行接收数据作为输入。
<deletebutton [receivedRow]='row'></deletebutton>
现在在我的 onClick
方法中说 receivedRow
未定义。我觉得缺少的是 [receivedRow]='row'
我的 deletebutton
HTML 和 HTML 中该子组件的 onClick
函数调用之间的协调。总的来说,我只想单击一行,单击按钮打开删除 Boostrap 模态,然后删除正确的行我单击模态内的 Delete
按钮。如果有什么不清楚或需要更多代码,请告诉我。
是否真的有一种方法可以像这样使用@Input 和@Output 在子组件之间进行通信?
使用angular2,你的数据流应该是:
- 向下传递数据
- 最多发送事件
所以如果你真的想走这条路,你应该有这样的东西:
我认为还有更好的方法:
对于您的应用程序和您的用户,最好在每一行都有一个删除按钮。这样,它可以避免用户混淆单击一行然后单击删除按钮,并且在您的代码中您将能够执行类似的操作:
src/app.html :
<table class="table">
<tr *ngFor="let row of tableData">
<td *ngFor="let column of row.columns">
{{ column.name }}
</td>
<td (click)="deleteRow(row)"><button>X</button></td>
</tr>
</table>
<button (click)="addRow()">Add a row</button>
src/app.ts (此处仅缩减为 class) :
@Component({
selector: 'app',
templateUrl: `./src/app.html`,
})
export class App {
private tableData;
private cptRow = 1;
constructor() {
this.tableData = [
{
idRow: `idR${this.cptRow++}`,
columns: [
{idColumn: 'idR1C1', name: 'Column 1-1'},
{idColumn: 'idR1C2', name: 'Column 1-2'},
{idColumn: 'idR1C3', name: 'Column 1-3'}
]
},
{
idRow: `idR${this.cptRow++}`,
columns: [
{idColumn: 'idR2C1', name: 'Column 2-1'},
{idColumn: 'idR2C2', name: 'Column 2-2'},
{idColumn: 'idR2C3', name: 'Column 2-3'}
]
},
{
idRow: `idR${this.cptRow++}`,
columns: [
{idColumn: 'idR3C1', name: 'Column 3-1'},
{idColumn: 'idR3C2', name: 'Column 3-2'},
{idColumn: 'idR3C3', name: 'Column 3-3'}
]
}
];
}
deleteRow(row) {
// we can do this by reference ...
// this.tableData = this.tableData.filter(r => r !== row);
// or by ID
this.tableData = this.tableData.filter(r => r.idRow !== row.idRow);
}
addRow() {
this.tableData.push({
idRow: `idR${this.cptRow}`,
columns: [
{idColumn: `idR${this.cptRow}C1`, name: `Column ${this.cptRow}-1`},
{idColumn: `idR${this.cptRow}C2`, name: `Column ${this.cptRow}-2`},
{idColumn: `idR${this.cptRow}C3`, name: `Column ${this.cptRow}-3`}
]
});
this.cptRow++;
}
}
这是一个可用的 Plunkr:http://plnkr.co/edit/hNhcdraoDNnI2C92TQvr?p=preview
现在,如果你真的想使用 input/output 属性,你应该寻找教程,因为这里的结构似乎有点混乱。我可以帮助你理解这一点(用 angular2 理解它很重要!)但也许你应该在 Gitter/Angular 上大声疾呼,而不是在这里详细说明 Angular2 流程 :)
一种解决方法是将删除按钮组件放置在 table 组件的 HTML 中,如下所示:
<ng-table [config]="config"
(tableChanged)="onChangeTable(config)"
(cellClicked)="onCellClick($event)"
[rows]="rows" [columns]="columns">
</ng-table>
<deletebutton [receivedRow]='toSend'></deletebutton>
并且仍然像我一样在主页的 HTML 中保留 table 的标签:
<app-datatable (row)="received($event)"></app-datatable>
现在该行的数据被发送到删除按钮,因为它在技术上是主页子组件的一部分。
仍然无法像我在问题中所问的那样在子组件之间进行通信。但这是可行的。
我有一个 ng-table
,它是我主页的子组件。单击一行时,它会使用 EventEmitter
通过 onCellClick
发送该行中的信息。我正在尝试将此信息发送到另一个子组件。这恰好是一个按钮,它是 Bootstrap 4 模式的子级,当单击主页上的按钮时弹出。只是在接收和处理该信息时遇到问题。
HTML 子组件 table:
<ng-table [config]="config"
(tableChanged)="onChangeTable(config)"
(cellClicked)="onCellClick($event)"
[rows]="rows" [columns]="columns">
</ng-table>
HTML 对于子组件(这出现在主页的 HTML):
<app-datatable (row)="received($event)"></app-datatable>
用于获取和发送行数据的 Typescript(this.row
是 EvenEmitter。data.row
是被点击的实际行):
@Output() row: EventEmitter<any> = new EventEmitter<any>();
public onCellClick(data: any): any {
let d = data.row.tDataPoint;
let i = data.row.tICCP;
let s = data.row.tStartDate;
let e = data.row.tEndDate;
let toSend:DataTable = new DataTable(d, i, s, e);
this.row.emit(toSend);
}
HTML 对于作为 Bootstrap 4 模态的子组件的按钮:
<button type="submit" class="btn" data-dismiss="modal" (click)="onClick($event)">Delete</button>
按钮子组件的打字稿:
selector: 'deletebutton'
@Input() receivedRow:DataTable;
onClick(message:DataTable){
this.sender.emit('This is from On Click Deletebutton');
console.log("On Click Deletebutton");
console.log(this.receivedRow);
for (let entry in DPS){
if (DPS[entry].tDataPoint===message.tDataPoint){
DPS.splice(parseInt(entry),1);
}
}
}
按钮子组件的 HTML(这出现在模态的 HTML 中)。这实际上应该从单击的行接收数据作为输入。
<deletebutton [receivedRow]='row'></deletebutton>
现在在我的 onClick
方法中说 receivedRow
未定义。我觉得缺少的是 [receivedRow]='row'
我的 deletebutton
HTML 和 HTML 中该子组件的 onClick
函数调用之间的协调。总的来说,我只想单击一行,单击按钮打开删除 Boostrap 模态,然后删除正确的行我单击模态内的 Delete
按钮。如果有什么不清楚或需要更多代码,请告诉我。
是否真的有一种方法可以像这样使用@Input 和@Output 在子组件之间进行通信?
使用angular2,你的数据流应该是:
- 向下传递数据
- 最多发送事件
所以如果你真的想走这条路,你应该有这样的东西:
我认为还有更好的方法:
对于您的应用程序和您的用户,最好在每一行都有一个删除按钮。这样,它可以避免用户混淆单击一行然后单击删除按钮,并且在您的代码中您将能够执行类似的操作:
src/app.html :
<table class="table">
<tr *ngFor="let row of tableData">
<td *ngFor="let column of row.columns">
{{ column.name }}
</td>
<td (click)="deleteRow(row)"><button>X</button></td>
</tr>
</table>
<button (click)="addRow()">Add a row</button>
src/app.ts (此处仅缩减为 class) :
@Component({
selector: 'app',
templateUrl: `./src/app.html`,
})
export class App {
private tableData;
private cptRow = 1;
constructor() {
this.tableData = [
{
idRow: `idR${this.cptRow++}`,
columns: [
{idColumn: 'idR1C1', name: 'Column 1-1'},
{idColumn: 'idR1C2', name: 'Column 1-2'},
{idColumn: 'idR1C3', name: 'Column 1-3'}
]
},
{
idRow: `idR${this.cptRow++}`,
columns: [
{idColumn: 'idR2C1', name: 'Column 2-1'},
{idColumn: 'idR2C2', name: 'Column 2-2'},
{idColumn: 'idR2C3', name: 'Column 2-3'}
]
},
{
idRow: `idR${this.cptRow++}`,
columns: [
{idColumn: 'idR3C1', name: 'Column 3-1'},
{idColumn: 'idR3C2', name: 'Column 3-2'},
{idColumn: 'idR3C3', name: 'Column 3-3'}
]
}
];
}
deleteRow(row) {
// we can do this by reference ...
// this.tableData = this.tableData.filter(r => r !== row);
// or by ID
this.tableData = this.tableData.filter(r => r.idRow !== row.idRow);
}
addRow() {
this.tableData.push({
idRow: `idR${this.cptRow}`,
columns: [
{idColumn: `idR${this.cptRow}C1`, name: `Column ${this.cptRow}-1`},
{idColumn: `idR${this.cptRow}C2`, name: `Column ${this.cptRow}-2`},
{idColumn: `idR${this.cptRow}C3`, name: `Column ${this.cptRow}-3`}
]
});
this.cptRow++;
}
}
这是一个可用的 Plunkr:http://plnkr.co/edit/hNhcdraoDNnI2C92TQvr?p=preview
现在,如果你真的想使用 input/output 属性,你应该寻找教程,因为这里的结构似乎有点混乱。我可以帮助你理解这一点(用 angular2 理解它很重要!)但也许你应该在 Gitter/Angular 上大声疾呼,而不是在这里详细说明 Angular2 流程 :)
一种解决方法是将删除按钮组件放置在 table 组件的 HTML 中,如下所示:
<ng-table [config]="config"
(tableChanged)="onChangeTable(config)"
(cellClicked)="onCellClick($event)"
[rows]="rows" [columns]="columns">
</ng-table>
<deletebutton [receivedRow]='toSend'></deletebutton>
并且仍然像我一样在主页的 HTML 中保留 table 的标签:
<app-datatable (row)="received($event)"></app-datatable>
现在该行的数据被发送到删除按钮,因为它在技术上是主页子组件的一部分。
仍然无法像我在问题中所问的那样在子组件之间进行通信。但这是可行的。