Angular12模板驱动嵌套表单中TinyMCE多实例动态取值问题
可行解决方案
以下提供三种适配不同场景的解决方案,可根据项目需求选择:
方案1:封装为自定义表单控件(推荐,符合Angular设计规范)
该方案完全适配模板驱动表单的取值逻辑,不需要处理内部name和standalone的冲突问题。
- 首先在
app-tinymce封装组件中实现ControlValueAccessor接口,注册自定义表单控件提供者:
import { Component, Input, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'app-tinymce', templateUrl: './tinymce.component.html', providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TinymceComponent), multi: true } ] }) export class TinymceComponent implements ControlValueAccessor { @Input() editorid: string; // 内部绑定编辑器内容 content: string = ''; // 表单控件回调方法 onChange = (value: string) => {}; onTouched = () => {}; writeValue(value: string): void { this.content = value || ''; } registerOnChange(fn: any): void { this.onChange = fn; } registerOnTouched(fn: any): void { this.onTouched = fn; } // 编辑器内容变化时同步给父表单 onContentChange(): void { this.onChange(this.content); this.onTouched(); } }
- 修改封装组件的模板绑定:
<editor [apiKey]="tinymceAPIKey" [id]="editorid" [(ngModel)]="content" [init]="tinyMCEEditorService.tinymceInitProp" (ngModelChange)="onContentChange()" > </editor>
- 父组件直接按普通表单控件调用即可:
<form #form="ngForm"> <app-tinymce editorid="myidone" name="myidone" [(ngModel)]="descriptionone" ></app-tinymce> <app-tinymce editorid="myidtwo" name="myidtwo" [(ngModel)]="descriptiontwo" ></app-tinymce> </form>
取值时直接调用this.form.value.myidone、this.form.value.myidtwo即可获取两个编辑器的独立值。
方案2:修复动态name绑定报错(不修改组件封装逻辑)
你之前动态绑定name报错的核心原因是ngModel初始化时机早于Input参数editorid的赋值时机,Angular识别不到动态生成的name属性,按如下方式修改即可:
- 封装组件模板中给
ngModel显式指定配置项,关联动态name:
<editor [apiKey]="tinymceAPIKey" [id]="editorid" [name]="editorid" [(ngModel)]="description" [init]="tinyMCEEditorService.tinymceInitProp" [ngModelOptions]="{standalone: false, name: editorid}" > </editor>
- 父组件传参时注意字符串常量的绑定写法:
<!-- 常量写法,不需要方括号 --> <app-tinymce editorid="myidone" ..></app-tinymce> <!-- 变量写法,方括号绑定组件内变量 --> <app-tinymce [editorid]="myidtwoVariable" ..></app-tinymce>
修改后不会再抛出name缺失错误,可直接通过this.form.value对应字段取值。
方案3:使用standalone属性的取值方案
如果必须设置standalone: true去掉name属性,可通过输出事件或实例引用取值:
- 封装组件添加内容变化的输出事件:
@Output() contentChange = new EventEmitter<string>(); // 编辑器内容变化时触发 onContentChange(value: string) { this.contentChange.emit(value); }
- 父组件监听事件存值,或者用
@ViewChild获取组件实例:
<app-tinymce editorid="myidone" (contentChange)="descriptionone = $event" #tinymceOneRef ></app-tinymce>
取值时可直接用组件内定义的this.descriptionone变量,或者调用this.tinymceOneRef.description获取实例内部的编辑器值。
内容的提问来源于stack exchange,提问作者user2869612
相关产品推荐
相关产品推荐

