【问题标题】:How to trigger Angular Mentions on button press in html?如何在html中按下按钮时触发Angular Mentions?
【发布时间】:2020-04-08 15:40:49
【问题描述】:

我创建了一个@ 和# 按钮来在我的WYSIWYG 编辑器上添加@ 和#,并希望通过单击html 按钮来触发角度提及。但是问题是,每当我按下按钮时,mention-list 标签就会弹出,但我无法对我提供的数据执行任何选择

下面的代码实际上触发了 Angular 的提及,但它也会在单击 @# 按钮后发出 close() 事件,因此我可以看到名称和日期作为弹出窗口 mention-list 标记在我的编辑器上,但无法选择其中任何一个。如何解决此问题,以便触发提及并选择姓名和日期,而不是之前发送 close() 事件?

组件 Html 文件

 <div id="controls">
  <button class="button btn-editor" (click)="insChar('@')">@</button>
  <button class="button btn-editor" (click)="insChar('#')">#</button>
 </div>
 <div id="editor" (closed)="closed()" contenteditable [mentionConfig]="mentionConfig" 
  placeholder="Jot something down..." > 
 </div>

组件 Typescript 文件

export class TextEditorComponent implements OnInit {

 tribute: string;
 mentionConfig: any;

 ngOnInit(){
 }

 constructor(){
   this.mentionConfig = {
      mentions: [
        {
            items: ['Alec', 'Joyce', 'Nalin', 'Dominic'],
            triggerChar: '@',
            mentionSelect: (item)=>{
              this.tribute = `@${item.name}`;
              return this.tribute;
            },
            labelKey: 'name',
            maxItems: 5, 
            disableSearch: false
        },
        {
            items: [ '20-12-13', '13-04-19', '16-12-11'],
            triggerChar: '#',
            mentionSelect: (item)=>{
              this.tribute = `#${item.date}`;
              return this.tribute;
            },
            labelKey: 'date',
            maxItems: 5, 
            disableSearch: false
        }
      ], 
    };
 }


 insChar(char: string){
    if(window.getSelection){
      document.getElementById('editor').focus();
      let r = window.getSelection().getRangeAt(0).cloneRange();
      window.getSelection().removeAllRanges();
      const a = document.createTextNode(`${char}`);

      let code = char==='@'?'Digit2':'Digit3';
      let event = new KeyboardEvent('keydown',{'key':`${char}`, 'code':`${code}`});

      r.insertNode(a);
      r.setStartAfter(a);
      this.sel.addRange(r);
      document.getElementById('editor').dispatchEvent(event);
    }
  }

  closed(){ // insert mentions
    console.log('closed');

    if(this.tribute !== '')
    {
      const input = document.createElement('input');
      input.setAttribute('value',`${this.tribute}`);
      input.setAttribute('type','button');
      input.style.border = 'none';
      input.style.padding = "3px";
      input.style.backgroundColor = '#dff6f0';
      input.style.color = '#2e279d';
      input.style.fontWeight = '';
      input.style.fontSize = 'inherit';
      input.style.cursor = 'pointer';
      const range = window.getSelection().getRangeAt(0);
      window.getSelection().removeAllRanges();

      let sp = document.createTextNode(' ');
      range.insertNode(input);
      range.insertNode(sp);
      range.setStartAfter(input);
      window.getSelection().addRange(range);
      this.tribute = '';
    }
  }
}

【问题讨论】:

    标签: javascript html node.js angular typescript


    【解决方案1】:

    您的#editor 元素具有(closed) 事件。在您的insChar() 方法中,您调用document.getElementById('editor').dispatchEvent(event);

    这将触发#editor 元素上的关闭事件。

    所以考虑将$event 传递给closed 方法:

    <div id="editor" (closed)="closed($event)" contenteditable [mentionConfig]="mentionConfig" 
      placeholder="Jot something down..." > 
    </div>
    

    并检查是什么触发了关闭事件,以过滤掉由您手动调度事件触发的事件。

    【讨论】:

    • 我试过这个,但是在插入 @ 或 # 之后触发了 close 事件。当我在closed(event){} 方法中执行console.log(event) 时,它会打印undefined
    • 关闭事件只触发一次
    • 您真正希望何时触发关闭事件。你在哪里触发它..你可以用这些细节更新你的问题
    • 太好了,这就是我在回答中想说的,您的调度事件正在触发关闭
    • 但是关闭事件总是在打开事件之前触发,但不知道为什么会发生
    【解决方案2】:
    insChar(char: string){
     if(window.getSelection){
          document.getElementById('editor').focus();
          let code = char==='@'?'Digit2':'Digit3';
          let event = new KeyboardEvent('keydown',{'key':`${char}`, 'code':`${code}`});
          document.getElementById('editor').dispatchEvent(event); //keyboard event first
    
          let r = window.getSelection().getRangeAt(0).cloneRange();
          window.getSelection().removeAllRanges();
          const a = document.createTextNode(`${char}`);
          r.insertNode(a);
          r.setStartAfter(a);
          window.getSelection().addRange(r); //inserting @ or # later
       }
    }
    

    closed() 事件总是首先触发,我不知道原因,但我意识到键盘事件实际上是在角度提及的opened() 事件之后触发的。不知何故,这段代码效果最好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-28
      • 2012-10-08
      • 1970-01-01
      • 2017-12-27
      • 2011-02-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多