用户输入时如何在表中动态添加行(postman-style-reactive-table)

时间:2019-01-10 20:38:06

标签: javascript html angular

当标题标签中的输入中至少有一个字符时(如Postman的行为),如何动态添加行。

1)当用户在第一行的td中输入任何单个字符时,则一行    应该在下面添加。当用户从第一行删除文本以及第一行的文本    td为空,然后删除下面的行。

2)跟踪模型中每个行输入(例如,键和    值);

3)当用户在任何td中的一行中输入任何单个字符时,则选中该复选框   应该检查,否则不要检查。

.ts

    model =  new Model ('','','',..............);
    tableRow = {
    "key":[{
    'name':'key1',
    'keyInput':""
    }],
    "value":[{
    'name':'value1',
    'keyInput':""
    }]
    }

addRow(event){
    if(event.target.length < 2){
     let data = {
           'name':'key' + (this.tableRow.key.length + 1),
           'keyInput':""
           }
         this.tableRow.key.push(data )
       }else{
        this.tableRow.key.pop();
         }
       }

.html

<div class="col-12 table-responsive">
<table class="table">
<thead>
<th>
<td></td>
<td>Key</td>
<td>Value</td>
</th>
</thead>
<tbody>
<tr *ngFor="let row of tableRow.key; let i = index;">
<td><input type="checkbox"></td>
<td><input (keyup)="addRow($event)" [(ngModel)]="model.key" type="text"></td>
<td><input [(ngModel)]="model.value" type="text"></td>
</tr>
</tbody>
</table>
</div>

2 个答案:

答案 0 :(得分:2)

这是您可能想要的非常基本的实现。

组件:

export class AppComponent {
  title = 'stack-solve';
  //defining row of objects and initializing first row with empty values
  //All values entered on the screen are bound to this array
  rows: any[] = [{
    checked:false,
    key:'',
    value:''
  }];

//This function is called on keyup and checks the checkbox on that row and adds new row if the action was on the last row  
checkAndAddRow(i){
    this.rows[i].checked = true;
    if(this.rows.length - 1 == i){//insert new empty row, incase this keyup event was on the last row, you might want to enhance this logic... 
      this.rows.push({
        checked:false,
        key:'',
        value:''
      })
    }

  }
}

模板:

  <div class="col-12 table-responsive">
    <table class="table">
      <thead>
        <td></td>
        <td>Key</td>
        <td>Value</td>
      </thead>
      <tbody>
        <tr *ngFor="let row of rows; let i = index">
          <td><input [checked]="row.checked" type="checkbox"></td>
          <td><input [(ngModel)]="row.key" type="text" name="key" (keyup)="checkAndAddRow(i)"></td>
          <td><input [(ngModel)]="row.value" type="text" name="value" (keyup)="checkAndAddRow(i)"></td>
        </tr>
      </tbody>
    </table>
  </div>

app.module:

imports: [
    BrowserModule,
    FormsModule // need to import FormsModule if you don't have already
  ],

答案 1 :(得分:1)

您的解决方案即将结束。我要修改的主要内容是跟踪行本身(而不是某些外部模型)上每一行的键/值/检查状态。这样,每一行都是自维护的,并且没有外部副作用来修改其他行(当然,除了添加/删除行之外)。

我更改的另一件事是捕获(input)事件,而不是(keyup)事件。这是为了更好地移动剪切/粘贴以及右键单击剪切/粘贴支持。 (keyup)将不会捕获这些事件中的任何一个。

Working Example Here

import {Component} from '@angular/core';

@Component({
  selector: "reactive-table",
  template: `
    <table>
      <thead>
        <tr>
          <th>Selected</th>
          <th>Key</th>
          <th>value</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let row of data.rows; let $index = index;">
          <td><input type="checkbox" [(ngModel)]="row.selected"/></td>
          <td><input [value]="row.key" (input)="handleKeyChange($event, row, $index)" /></td>
          <td><input [(ngModel)]="row.value" /></td>
        </tr>
      </tbody>
    </table>
  `,
  styles: [`

  `]
})
export class ReactiveTableComponent {
  public data;
  constructor() {

  }
  ngOnInit() {
    this.data = {
      rows: [
        {
          selected: false,
          key: "",
          value: "",
          oldKey: ""
        }
      ]
    }
  }
  handleKeyChange(event, row, rowIndex) {
    var newKey = event.target.value;
    if (newKey !== row.oldKey) {
      row.selected = true;
    }
    if (newKey === "" && rowIndex === this.data.rows.length -2) {
      this.data.rows.pop();
      row.selected = false;
    }
    else if (newKey !== "" && row.oldKey === "" && rowIndex === this.data.rows.length -1) {
      this.data.rows.push({
        selected: false,
        key: "",
        value: "",
        oldKey: ""
      });
    }
    row.oldKey = row.key = newKey;
  }
}