Событие щелчка по вставленной кнопке в раздел с возможностью редактирования содержимого не работает

#javascript #html #angular #dom #dom-events

#javascript #HTML #angular #dom #dom-события

Вопрос:

У меня есть раздел с возможностью редактирования содержимого. Для управления им я использую следующую директиву:

 <div
   class="msg-input-area"
   [class.focused]="isMsgAreaFocused"
   contenteditable
   [contenteditableModel]="msgText"
   (contenteditableModelChange)="onMsgTextChange($event)"
   (contenteditableModelSubmit)="onMsgSend()"
   (removeHashSign)="removeHashSign()"
   placeholder="Compose your comment here"
   tabindex="0"
   (focus)="isMsgAreaFocused = true"
   (blur)="isMsgAreaFocused = false"
   #msgInputArea
></div>






@Directive({
    selector: '[contenteditableModel]',
    host: {
        '(blur)': 'onEdit()',
        '(keydown)': 'onKeyDown($event)',
        '(keyup)': 'onEdit()'
    }
})
export class ContentEditableDirective implements OnChanges {
    @Input('contenteditableModel') model: string;
    @Output('contenteditableModelChange') valueChanges = new EventEmitter<string>();
    @Output('contenteditableModelSubmit') submit = new EventEmitter<void>();
    @Output('removeHashSign') removeHashSign = new EventEmitter<void>();

    constructor(private elementRef: ElementRef<HTMLElement>) {}

    ngOnChanges(changes: SimpleChanges) {
        if (changes.model) {
            this.refreshView();
        }
    }

    onEdit(): void {
        const value = this.elementRef.nativeElement.innerText;
        this.valueChanges.emit(value);
    }

    onKeyDown(event: KeyboardEvent): void {
        if (!(event.ctrlKey || event.metaKey) amp;amp; event.code === 'Enter') {
            // submit
            this.valueChanges.emit(this.elementRef.nativeElement.innerHTML);
            this.submit.emit();
            event.preventDefault();
            return;
        } else if (event.code === 'Backspace' amp;amp; this.model[this.model.length - 1] === '#') {
            // remove #
            this.removeHashSign.emit();
            return;
        }
        this.onEdit();
    }

    private refreshView(): void {
        if (!this.model) {
            this.elementRef.nativeElement.textContent = this.model;
        } else if (this.model?.includes('<button')) {
            this.elementRef.nativeElement.innerHTML = this.model;
        }
    }
}

 

Если введен знак #, то элемент button добавляется внутри DIV

 ... => {
       let msgWithTag = this.msgText.slice(0, -1);
       msgWithTag  = this.generateLinkTag(tag);
       this.msgText = msgWithTag;
}

...

private generateLinkTag(tag: IConversationTag): string {
        return `<button style="color: #0d95db; font-weight: 600; cursor: pointer;">#${tag.name}</button>amp;nbsp;`;
}
 

Пока все хорошо. Кнопка отображается внутри DOM.

Как я могу добавить событие (щелчок) к кнопке?

Я пробовал несколько способов:

 return `<button (click)="() => myFunc()" style="color: #0d95db; font-weight: 600; cursor: pointer;">#${tag.name}</button>amp;nbsp;`;


and

ngAfterViewInit() {
        const parser = new DOMParser();
        const doc = parser.parseFromString(myString, 'text/html');
        doc.body.childNodes.forEach((node: ChildNode) => {
            if (node.nodeName.toLowerCase() === 'button') {
                console.log(node)
                node.addEventListener('click', () => {
                    console.log('click')
                });
            }
        });
        if (this.msgContent) {
            this.msgContent.nativeElement.innerHTML = doc.body.innerHTML;
        }
}
 

В обоих случаях (щелчок) функции обратного вызова не вызываются.

Ответ №1:

Для обработчика щелчка по кнопке синтаксис должен быть (click)="myFunc()" таким: where myFunc — это функция, определенная в вашем компоненте.

https://angular.io/guide/event-binding