簡體   English   中英

使用renderer2 Angular在按鍵時將字符包裹在span元素中

[英]Wrap a character in a span element on key press with renderer2 Angular

我有一個 contenteditable div,它在用戶按下“@”時觸發一個事件。 它的作用是將按下的@ 字母包裹在相同位置的自定義元素中。

這是代碼

    <div  contenteditable="true" role="textarea" (keydown.@)= "onWrap()">
    </div>
    onWrap() {
        setTimeout(() => {
          const caretPosition = window.getSelection().getRangeAt(0);
          const range = document.createRange();
          range.setStart(caretPosition.commonAncestorContainer, caretPosition.startOffset - 1);
          range.setEnd(caretPosition.commonAncestorContainer, caretPosition.endOffset );
          const previousNode = (range.cloneContents().lastChild as HTMLElement);
          const newWrap = this.renderer.createElement('my-custom-component');
          //range.surroundContents(newWrap );
        }, 10);
      }

所以在@press 之后,可編輯的文本必須變成

    <div  contenteditable="true" role="textarea">
    this is my editable content and i want to insert here <my-custom-component>@</my-custom-component> and the rest of the text
    </div>

我想要轉換<my-custom-component>

  1. 我暫時使用了 aroundContents,但不推薦使用它,並且自定義組件沒有改變。 也許我必須使用 renderer.appendChild 但我不知道如何使用。
  2. 我正在使用超時,因為在按鍵上沒有檢測到 @,我不想使用它。

如評論中所述,您可以利用ComponentRendererFactory並動態創建和附加組件。 您需要的是注入所需的服務。 解析組件工廠需要InjectorApplicationRef是將組件附加到DOM

constructor(
    private injector: Injector,
    private cfr: ComponentFactoryResolver,
    private applicationRef: ApplicationRef
  )

定義一個虛擬組件:

@Component({
  selector: "app-wrapper",
  styleUrls: ["./wrapper.component.css"],
  template: `
    <span style="background-color:aqua">
      x:
      {{ innerText }}
    </span>
  `
})
export class WrapperComponent {
  innerText: string;
}

動態創建組件

 const wrap = this.renderer.createElement("wrapper-container"); // this can be anything but it is required
    const factory = this.cfr.resolveComponentFactory<WrapperComponent>(WrapperComponent);
    const cmp = factory.create(this.injector, [], wrap); // attach your component into host element : `wrapper-container`
    this.applicationRef.attachView(cmp.hostView); // attach component into DOM   
    const contents = range.extractContents(); // extract contents
    cmp.instance.innerText = contents.textContent; // set components text   
    range.insertNode(wrap); // insert everything into range.

這是 Stackblitz 示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM