Angular15+ngx-quill v21.0.0结合FormBuilder无法获取编辑器值
解决Angular 15 + ngx-quill v21.0.0表单绑定无法获取编辑器值的问题
问题现象
使用FormBuilder创建表单并绑定ngx-quill编辑器后,出现以下异常:
- 编辑器输入内容后,
content表单控件值始终为null controls.content.errors.required持续为truecontrols.content.touched始终为false
解决方案
1. 修正表单控件初始值
将content控件的初始值从null改为空字符串''。ngx-quill与表单控件绑定时,初始null会导致值更新逻辑无法正常触发,同时required验证规则对null会直接判定不通过:
// 在ngOnInit中修改表单构建代码 this.blogForm = this.fb.group({ title: ['', Validators.required], content: ['', Validators.required], // 替换null为'' });
2. 确保QuillModule正确导入
在当前组件所属模块(如AppModule)中导入QuillModule并调用forRoot(),这是ngx-quill集成Angular表单的必要配置:
import { QuillModule } from 'ngx-quill'; @NgModule({ imports: [ // ...其他模块导入 QuillModule.forRoot() ] }) export class YourModule { }
3. 移除自定义Enter键盘绑定
你配置的keyboard.bindings.enter会阻断Quill的默认输入行为,导致编辑器内容变化无法同步到表单控件。直接删除该绑定配置:
// 修改quillConfig中的keyboard配置 keyboard: { bindings: { // 移除以下enter绑定代码 // enter: { // key: 13, // handler: (range: any, context: any) => { // console.log('enter'); // return true; // }, // }, }, },
4. 手动标记控件为touched(可选)
如果编辑器的blur事件未正确触发控件的touched状态,在onBlur方法中手动设置:
// 在组件类中添加onBlur方法 onBlur() { this.blogForm.get('content')?.markAsTouched(); }
5. 验证依赖版本兼容性
确认package.json中依赖版本匹配:
- Angular 15 与 ngx-quill v21.x版本兼容
- 确保
quill版本符合ngx-quill v21.x的要求(通常为v1.3.7+)
调整后的代码参考
editor.component.ts
quillConfig = { toolbar: { container: [ ['bold', 'italic', 'underline', 'strike'], ['code-block'], [{ header: 1 }, { header: 2 }], [{ list: 'ordered' }, { list: 'bullet' }], ['clean'], ['link'], ], }, mention: { allowedChars: /^[A-Za-z\sÅÄÖåäö]*$/, mentionDenotationChars: ['@', '#'], source: ( searchTerm: string, renderList: (arg0: any[], arg1: any) => void, mentionChar: string ) => { let values; if (mentionChar === '@') { values = this.atValues; } else { values = this.hashValues; } if (searchTerm.length === 0) { renderList(values, searchTerm); } else { const matches = []; for (var i = 0; i < values.length; i++) if ( ~values[i].value.toLowerCase().indexOf(searchTerm.toLowerCase()) ) matches.push(values[i]); renderList(matches, searchTerm); } }, }, 'emoji-toolbar': true, 'emoji-textarea': false, 'emoji-shortname': true, keyboard: { bindings: { // 已移除enter绑定 }, }, }; constructor(private fb: FormBuilder) {} ngOnInit(): void { this.blogForm = this.fb.group({ title: ['', Validators.required], content: ['', Validators.required], // 修正初始值 }); } onSubmit() { console.log(this.blogForm.value); console.log(this.blogForm); } onBlur() { this.blogForm.get('content')?.markAsTouched(); // 手动标记touched }
editor.component.html
<div class="tt-form-container"> <form class="tt-blogForm" [formGroup]="blogForm" (ngSubmit)="onSubmit()"> <h2>Write a Blog</h2> <div> <label for="title"> Title:</label> <input type="text" id="title" formControlName="title" /> </div> <div> <label for="content">Content:</label> <quill-editor class="tt-blog-editor" theme="snow" formControlName="content" [modules]="quillConfig" (onBlur)="onBlur()" > </quill-editor> </div> <div> <button class="tt-blog-button" type="submit">Submit</button> </div> </form> </div>
内容的提问来源于stack exchange,提问作者shubham hirap
相关产品推荐
相关产品推荐

