首页 文章

在Angular 2子组件之间使用@input和@output

提问于
浏览
0

我有 ng-table 这是我主页的子组件 . 单击一行时,它将使用 EventEmitter 通过 onCellClick 发送该行中的信息 . 我正在尝试将此信息发送给另一个子组件 . 这恰好是一个按钮,它是Bootstrap 4模式的子项,当单击主页面上的按钮时会弹出该按钮 . 只是在接收和操纵该信息时遇到问题 .
This is the main page. The Bootstrap modal pops up whe the center button of the set of three is clicked.

Bootstrap modal

子组件表的HTML:

<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>

按钮子组件的Typescript:

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在这样的子组件之间进行通信吗?

2 回答

  • 1

    使用angular2,您的数据流应该是:

    • down to pass data
    • up to send events

    所以,如果你真的想这样,你应该有类似的东西:

    diagram

    I think there's a better way tho :
    对于您的应用和您的用户,它'd be best to have a remove button on each line. This way, it avoid the user to be confused clicking on a row and then click on a remove button and within your code you'将能够做这样的事情:

    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

    现在,如果你真的想使用输入/输出属性,你应该寻找教程,因为这里的结构似乎有点困惑 . 我可以帮助你理解(并且用angular2来理解它很重要!)但也许你应该在Gitter/Angular上给我一个喊叫,而不是在这里详细说明Angular2流程:)

  • 0

    一些解决方法是将删除按钮组件放在表组件的HTML中,如下所示:

    <ng-table [config]="config"
          (tableChanged)="onChangeTable(config)"
          (cellClicked)="onCellClick($event)"
          [rows]="rows" [columns]="columns">
    </ng-table>
    <deletebutton [receivedRow]='toSend'></deletebutton>
    

    并且仍然将表格的标签留在主页面的HTML中,就像我拥有它一样:

    <app-datatable (row)="received($event)"></app-datatable>
    

    现在行的数据被发送到该删除按钮,因为它在技术上是主页面的子组件的一部分 .

    仍然无法像我在问题中提到的那样在子组件之间进行通信 . 但这有点接近有效 .

相关问题