使用renderer2 Angular在按键上的span元素中包裹一个字符

问题描述 投票:0回答:1

我有一个内容可编辑的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);
      }

因此@按下后,可编辑文本必须变为

    <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. 我目前正在使用SurroundContents,但未要求使用它,并且自定义组件未更改。也许我必须使用renderer.appendChild,但我不知道如何。
  2. 我正在使用超时,因为在按键时未检测到@,并且我不想使用它。

我有一个内容可编辑的div,当用户按下'@'时会触发一个事件。它的作用是将按下的@字母包装在同一位置的自定义元素中。这是代码

]] >>

如评论中所述,您可以利用ComponentRendererFactory并动态创建和附加组件。您需要的是注入所需的服务。解决组件工厂需要使用Injector,并且ApplicationRef用于将组件连接到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 sample

angular selection renderer appendchild
1个回答
0
投票

如评论中所述,您可以利用ComponentRendererFactory并动态创建和附加组件。您需要的是注入所需的服务。解决组件工厂需要使用Injector,并且ApplicationRef用于将组件连接到DOM

© www.soinside.com 2019 - 2024. All rights reserved.