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

Angular 5 + QuillJS [Parchment]:自定义标签扩展报错求助

Fixing Custom Non-Editable Tags in PrimeNG Editor (Quill Under the Hood)

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 ngOnInit instead of ngAfterViewInit.
  • Content is still editable: Double-check that contenteditable="false" is set in the create method. If Quill is overriding it, add pointer-events: none to your custom CSS class to block interaction entirely.
  • PrimeNG toolbar conflicts: If adding a custom toolbar button, configure PrimeNG’s toolbar property to include your button ID, then bind the click event to your insertNonEditableBlock method.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 06:43:36