ngModel 只接受 Angular 中的一个字符更改 2

ngModel accepts just one character change in Angular 2

下图是我的table动态设置数据的地方。例如,它可以有 2,3,4 ... 列。

我的html代码如下:<thead>包含标题值,tbody包含可以修改的值。

<table class="table-conf">
    <thead>
       <tr>
           <th *ngFor="let data of jsonText[0]" style="text-align: center;">{{data}}</th>
       </tr>
    </thead>
    <tbody>
       <tr *ngFor="let data of jsonText; let i=index">
         <ng-container *ngIf="i!=0">
             <td class="padding-table" *ngFor="let dt of data; let j=index">
                 <input style="text-align: center;" [(ngModel)]="jsonText[i][j]">
             </td>
         </ng-container>
       </tr>
    </tbody>
</table>

下面是我迭代的 jsonText 变量的示例:

jsonText Array(6)
     0: (2) ["Task", "Hours per Day"]
     1: (2) ["Work", 11]
     2: (2) ["Eat", 2]
     3: (2) ["Commute", 2]
     4: (2) ["Watch TV", 2]
     5: (2) ["Sleep", 7]

问题是:当我尝试修改 table 中的元素时,我一次只能修改一个字符。例如:如果我想把"Eat"改成"Lunch",我需要删除"Eat",然后写L,再点击输入,写u , 再次点击等...

有人能帮帮我吗?

你的 ngFor 绑定到 jsonText,所以每次你编辑 jsonText[i][j],你都会强制 ngFor 指令重新计算,这就是为什么你失去了焦点。

这种情况下,直接绑定到'dt'

即可
 <input style="text-align: center;" [(ngModel)]="dt">

这样您就可以编辑带有json文本的字段,而不是整个对象。

此外,如果 dt 在模型中不起作用,那么 dt 可能不是您期望的那样。

在您的 html 模板中添加一行以显示 dt 的值。

<tbody>
   <tr *ngFor="let data of jsonText; let i=index">
     <ng-container *ngIf="i!=0">
         <td class="padding-table" *ngFor="let dt.value of data; let j=index">
             {{dt.value | json}} // Add this
         </td>
     </ng-container>
   </tr>
</tbody>

解决方案

问题出在您的 json 数据上。 json文本数组只是字符串或数字数组的数组。不是 'objects',所以它们没有绑定到任何变量。这就是为什么 ngModel 在 'dt' 上不起作用的原因。 dt 没有给定变量。

因此,将 json 文本数组的设置方式更改为如下所示:

jsonText = [
  [{ value: "task", id: 0}, {value: "Hours per day", id: 1}],
  [{ value: "work", id: 2}, {value: "11", id: 3}],
  [{ value: "eat", id: 4}, {value: "commute", id: 5}],
  ....
]

Working Example

正如其他答案中所说的那样,当您将 jsonText 绑定到 ngModel 然后 ngFor 重新评估时,您会失去对输入的关注。

并且当您执行 [(ngModel)]="dt" 时,ngModel 无法绑定到动态创建的变量。 所以你面对this issue.

所以要让它发挥作用:

(a) 您必须将 trackBy 函数应用到您的 ngForRead

所以在 HTML 中添加 trackBy 功能,并像 [(ngModel)]="data[j] 那样进行绑定,例如:

 <tr *ngFor="let data of jsonText; let i=index">
         <ng-container *ngIf="i!=0">
             <td class="padding-table" *ngFor="let dt of data; let j=index; trackBy:customTrackBy">
                 <input style="text-align: center;" [(ngModel)]="data[j]">
             </td>
         </ng-container>
</tr>

(b) 并在您的组件中添加函数并跟踪索引。

     customTrackBy(index: number, obj: any): any {
         return index;
     }