在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>
关键修改说明
- 上下文传递整个对象:把
[ngTemplateOutletContext]中的data.n0替换为整个item(原data),这样模板可以访问到对象的可写属性。 - 绑定对象属性:
[(ngModel)]="item.n0"绑定的是对象的属性,而非只读的模板变量,双向绑定可以正常工作。 - 补全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
相关产品推荐
相关产品推荐

