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

Angular6集成Quill.js遇Quill未定义错误的技术问询

Fixing "ReferenceError: Quill is not defined" in Angular 6 + Quill.js Integration

Let's break down the two key issues you're facing and walk through the fixes step by step:

1. Quill Can't Attach to a <textarea> Element

First off, Quill.js doesn't work with <textarea> elements directly. It replaces the target DOM element with its own rich editor structure, so you need to swap your <textarea> for a <div> container. Since we can't use formControlName directly on a div, we'll manually sync the editor content with your form control.

Update your template to use a div (and add a template reference for easier access in your component):

<div #questionDescription class="form-control" [ngClass]="validateField('questionDescription')"></div>

2. Quill Isn't Being Loaded by Angular's Build System

Your declare var Quill: any; tells TypeScript that Quill exists, but Angular's bundler isn't actually loading Quill's JavaScript and CSS into the browser. You have two solid options to fix this:

Option 1: Add Quill to angular.json (Global Load)

Open your angular.json file, find the architect > build > options section, and add Quill's CSS and JS to the styles and scripts arrays:

"styles": [
  "src/styles.css",
  "node_modules/quill/dist/quill.snow.css"
],
"scripts": [
  "node_modules/quill/dist/quill.js"
]

This loads Quill globally across your app.

Option 2: Import Quill Directly in Your Component (Tree-Shaking Friendly)

This is the cleaner approach for component-specific usage. Remove the declare var Quill: any; line, then import Quill and its CSS directly in your component:

import Quill from 'quill';
import 'quill/dist/quill.snow.css';

Angular will bundle only what's needed for this component.

Full Working Example

Here's how to tie it all together with form sync:

Component TypeScript

import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import Quill from 'quill';
import 'quill/dist/quill.snow.css';

@Component({
  selector: 'app-new-practice-question',
  templateUrl: './new-practice-question.component.html',
  styleUrls: ['./new-practice-question.component.css']
})
export class NewPracticeQuestionComponent implements AfterViewInit {
  practiceQuestionForm = new FormGroup({
    questionDescription: new FormControl('', Validators.required)
  });

  @ViewChild('questionDescription') quillContainer!: ElementRef;
  private quillInstance!: Quill;

  ngAfterViewInit(): void {
    // Initialize Quill editor
    this.quillInstance = new Quill(this.quillContainer.nativeElement, {
      theme: 'snow'
    });

    // Sync initial form value to the editor
    const initialValue = this.practiceQuestionForm.get('questionDescription')?.value;
    if (initialValue) {
      this.quillInstance.root.innerHTML = initialValue;
    }

    // Sync editor changes back to the form control
    this.quillInstance.on('text-change', () => {
      this.practiceQuestionForm.get('questionDescription')?.setValue(this.quillInstance.root.innerHTML);
    });
  }

  validateField(fieldName: string) {
    const field = this.practiceQuestionForm.get(fieldName);
    return { 'is-invalid': field?.invalid && (field.dirty || field.touched) };
  }
}

Component Template

<form [formGroup]="practiceQuestionForm">
  <div #questionDescription class="form-control" [ngClass]="validateField('questionDescription')"></div>
  
  <!-- Show validation error if needed -->
  <div *ngIf="practiceQuestionForm.get('questionDescription')?.invalid && (practiceQuestionForm.get('questionDescription')?.dirty || practiceQuestionForm.get('questionDescription')?.touched)" class="invalid-feedback">
    Question description is required.
  </div>
</form>

Key Takeaways

  • Always use a <div> (not <textarea>) as the Quill container
  • Ensure Quill's JS and CSS are properly loaded either via angular.json or component imports
  • Manually sync Quill content with your Angular form control using the editor's text-change event

内容的提问来源于stack exchange,提问作者Manu Chadha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:57:34