You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在ng-template中使用ngModel遇模板变量只读错误,求解决方案

解决Angular + PrimeNG动态单元格编辑时的模板变量只读错误

你遇到的Error Cannot assign value $event to template variable data. Template variables are read-only.错误,核心原因是:模板中通过let-data声明的变量是只读的模板上下文变量,而[(ngModel)]的双向绑定会尝试修改这个变量,因此触发了Angular的只读限制。

解决方案:传递可写的数据路径而非原始值

最直接的修复方式是传递整个数据对象到模板上下文,绑定对象的属性(而非原始值),因为对象属性是可写的,不会触发只读限制:

<tr *ngFor="let item of tableData">
    <ng-container
       [ngTemplateOutletContext]="{ $implicit: item }"
       [ngTemplateOutlet]="isEditable ? editableCell : readOnlyCell"
    ></ng-container>
</tr>

<ng-template let-item #editableCell>
  <td pEditableColumn>
    <p-cellEditor>
      <ng-template pTemplate="input">
        <input
          class="edit-field-input"
          type="number"
          [(ngModel)]="item.n0"
        />
      </ng-template>
      <ng-template pTemplate="output">
        {{ item.n0 }}
      </ng-template>
    </p-cellEditor>
  </td>
</ng-template>

<ng-template let-item #readOnlyCell>
  <td>
    <p-cellEditor>
      <ng-template pTemplate="output">
        {{ item.n0 }}
      </ng-template>
    </p-cellEditor>
  </td>
</ng-template>

关键修改说明

  1. 上下文传递整个对象:把[ngTemplateOutletContext]中的data.n0替换为整个item(原data),这样模板可以访问到对象的可写属性。
  2. 绑定对象属性:[(ngModel)]="item.n0"绑定的是对象的属性,而非只读的模板变量,双向绑定可以正常工作。
  3. 补全PrimeNG组件模板:给editableCell添加了pTemplate="output",符合p-cellEditor的完整使用规范,确保编辑状态切换时显示正常。

备选方案(仅需传递单个属性时)

如果场景限制必须传递单个属性,可通过上下文传递回调函数同步修改:

<tr *ngFor="let data of tableData">
    <ng-container
       [ngTemplateOutletContext]="{ 
         $implicit: data.n0, 
         updateValue: (val) => data.n0 = val 
       }"
       [ngTemplateOutlet]="isEditable ? editableCell : readOnlyCell"
    ></ng-container>
</tr>

<ng-template let-value let-updateValue="updateValue" #editableCell>
  <td pEditableColumn>
    <p-cellEditor>
      <ng-template pTemplate="input">
        <input
          class="edit-field-input"
          type="number"
          [ngModel]="value"
          (ngModelChange)="updateValue($event)"
        />
      </ng-template>
      <ng-template pTemplate="output">
        {{ value }}
      </ng-template>
    </p-cellEditor>
  </td>
</ng-template>

通过updateValue回调把输入值同步回原数据对象,绕开模板变量的只读限制。

内容的提问来源于stack exchange,提问作者manjiro sano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 13:35:13