Angular 5 + QuillJS [Parchment]:自定义标签扩展报错求助
Hey there! I totally feel your frustration—spending days troubleshooting a feature that should work per the docs is such a drag. Let’s walk through exactly how to build that non-editable custom tag for PrimeNG Editor, since it’s just a wrapper around Quill, and there are a few easy-to-miss gotchas with PrimeNG’s implementation.
First: Grab the Correct Quill Instance
PrimeNG wraps Quill, so you can’t just use a global Quill instance—you need the one tied directly to your Editor component. This is a super common source of errors:
import { Component, ViewChild, AfterViewInit } from '@angular/core'; import { Editor } from 'primeng/editor'; import Quill from 'quill'; @Component({ // Your component metadata here }) export class YourEditorComponent implements AfterViewInit { @ViewChild('editor') editor!: Editor; private quillInstance: Quill | undefined; ngAfterViewInit() { // Fetch the underlying Quill instance from PrimeNG's Editor this.quillInstance = this.editor.quill; } }
Step 1: Create a Custom Non-Editable Blot
Quill uses "blots" to define custom content types. For a block-level non-editable tag, extend Quill’s base Block blot, mark it as non-editable, and register it before the Quill instance initializes (do this in ngOnInit, not ngAfterViewInit):
ngOnInit() { const Block = Quill.import('blots/block'); class CustomNonEditableBlock extends Block { // Unique identifier for your blot (used when inserting) static blotName = 'custom-non-editable'; // The HTML tag your blot will render as static tagName = 'MY-CUSTOM-TAG'; // Optional class for styling static className = 'custom-locked-block'; static create(value: { content: string }) { const node = super.create(value); // Mark the element as non-editable node.setAttribute('contenteditable', 'false'); // Add your custom content and styling node.textContent = value.content; node.style.padding = '8px'; node.style.backgroundColor = '#f5f5f5'; node.style.border = '1px solid #ddd'; return node; } // Extract value from the DOM element (for saving/serializing) static value(node: HTMLElement) { return { content: node.textContent || '' }; } } // Register the blot with Quill Quill.register(CustomNonEditableBlock, true); }
Step 2: Add a Way to Insert Your Custom Tag
Add a button (either in PrimeNG’s custom toolbar or your component template) to insert the non-editable block:
insertNonEditableBlock() { if (!this.quillInstance) return; const selection = this.quillInstance.getSelection(); if (!selection) return; // Insert the custom blot at the current cursor position this.quillInstance.insertEmbed( selection.index, 'custom-non-editable', { content: 'This content cannot be edited!' }, 'user' ); // Move the cursor to the line after the non-editable block this.quillInstance.setSelection(selection.index + 1, 0); }
Troubleshooting Common Errors
Here are fixes for the most frustrating issues you might be hitting:
- "Blot not found" error: You registered the blot after Quill initialized. Move your blot registration to
ngOnInitinstead ofngAfterViewInit. - Content is still editable: Double-check that
contenteditable="false"is set in thecreatemethod. If Quill is overriding it, addpointer-events: noneto your custom CSS class to block interaction entirely. - PrimeNG toolbar conflicts: If adding a custom toolbar button, configure PrimeNG’s
toolbarproperty to include your button ID, then bind the click event to yourinsertNonEditableBlockmethod.
Example CSS for Your Custom Block
Add this to your component’s styles to make the non-editable state obvious:
.custom-locked-block { pointer-events: none; /* Prevent clicks/selection */ user-select: none; /* Prevent text selection */ opacity: 0.8; }
I hope this gets you past that annoying error—Quill’s API is powerful but has those tiny timing and instance-specific quirks that trip up even experienced devs.
内容的提问来源于stack exchange,提问作者antonyboom

