Angular 2 innerHTML (щелчок) привязка
У меня было такое большое html-меню, которое я решил привязать, чтобы иметь возможность выпустить несколько подменю и избежать дублирования кода HTML. Родительский > дочерний (родительский) > дочерний...
В контексте: В ng2_msList/msList.components.ts импортируется ColumnsManagements.ts как this.ColumnsManagementInstance.
Меню innerHTML отображается правильно, в ng2_msList/pages/list.html:
<!-- COLUMNS DROPDOWN BUTTON -->
<ul [innerHTML]="msList.ColumnsManagementInstance.columnMenu" class="dropdown-menu" role="menu"> </ul>
С (в очень упрощенной версии моего кода): (Благодаря этому Stack Q)
setHtmlColumnsMenu() {
var self = this;
var htmlcolumnsmenu = '';
[...]
htmlcolumnsmenu += this.createColumnsList(this.getNoneRelationalColumns(true));
// which return something like a lot of html content and sometime in it :
// <a href="javascript:;" (click)="msList.ColumnsManagementInstance.toogleColumn(column)">
[...]
return htmlcolumnsmenu;
}
BUT (click) = "msList.ColumnsManagementInstance.toogleColumn(column)" (ранее в html-контенте) больше не работает. Он писал в представлении как простой текст в теге (до innerHTML он не отображался).
Я не могу найти способ сделать это снова. Я тестирую несколько способов вызова функции или, как я нашел в веб-ссылках, как на раздел Ang Doc, здесь.
Эти примеры называют функцию, которая очень легко устанавливается в том же файле/контексте (щелкните) = "MyAction()", но в моем контексте я не могу получить способ правильно ее называть.
Архитектура приложения может быть не такой, как Angular2 ожидание вызова.
Ответы
Ответ 1
Это по дизайну. Angular не обрабатывает HTML, добавленный с помощью [innerHTML]="..."
(кроме санировки) любым способом. Он просто передает его в браузер и что он.
Если вы хотите добавить HTML динамически, который содержит привязки, вам нужно обернуть его в компонент Angular2, затем вы можете добавить его, используя, например, ViewContainerRef.createComponent()
Для полного примера см. Angular 2 динамических вкладки с выбранными вами компонентами с кликом
Менее интерактивным способом было бы ввести ElementRef
, получив добавленный HTML, используя
elementRef.nativeElement.querySelector('a').addEventListener(...)
Ответ 2
Возможно, слишком поздно, но я надеюсь, что это поможет кому-то.
Так как вы хотите привязку привязки (и, возможно, другие привязки), лучше пропустить, используя [innerHTML]="..."
и создать внутренний компонент, с которым вы передаете данные через @Input()
аннотация.
Конкретно, у изображения есть компонент с именем BaseComponent, где вы устанавливаете некоторый код HTML для переменной htmlDatastrong > :
let htmlData = '...<button (click)="yourMethodThatWontBeCalled()">Action</button>...'
Затем в BaseComponent html файле вы привязываете его, как показано ниже:
...<div [innerHTML]="htmlData"></div>...
Вместо этого, вы создаете InnerComponent.ts:
@Component({
selector: 'inner-component',
templateUrl: './inner-component.html',
styleUrls: ['./inner-component.scss']
})
export class InnerComponent {
@Input()
inputData: any;
methodThatWillBeCalled(){
//do you logic on this.inputData
}
}
InnerComponent Html файл:
...<button (click)="methodThatWillBeCalled()">Action</button>...
Теперь в BaseComponent Html файле:
...<inner-component [inputData]="PUT_HERE_YOUR_DATA"></inner-component>
Ответ 3
Мне удалось настроить прослушиватели кликов для html, которые пришли из API в innerHtml.
-
HTML-код из API должен был быть заключен в набор div, чтобы он не отображался.
<div id='wholeHtml' style='display:none;'> <h2>Foo Bar Inc.</h2>... <button class="buttonToClick">Click me</button> </div>
-
Шаблон, в который попал html, также нужно было обернуть в target. Обратите внимание на канал " safeHtml ", который сообщает Angular, что этому источнику нужно доверять (это был API, которым я управлял).
<div id="parentDiv"> <div [innerHTML]="apiData | safeHtml"></div> </div>
-
В соответствующем компоненте использовались ElementRef и Renderer2 для копирования скрытого элемента div из API (который не позволял принимать прослушиватель щелчков), вставки его в родительский элемент div, настройки отображения недавно вставленного содержимого и применения прослушивателей щелчков.
import { Component, OnInit, ElementRef, Renderer2 } from '@angular/core';...
export class ExampleComponent implements OnInit { constructor(private elRef: ElementRef, private renderer: Renderer2) {} ngOnInit() {} ngAfterViewInit() { if(document.getElementById('wholeHtml')){ let allContent = this.elRef.nativeElement.querySelector('#wholeHtml'); let parentContainer = this.elRef.nativeElement.querySelector('#parentDiv'); this.renderer.appendChild(parentContainer, allContent); this.renderer.removeStyle(allContent, "display"); let clickButtons = this.elRef.nativeElement.querySelectorAll('.buttonToClick'); for(var я = 0; я < clickButtons.length; i++){ this.renderer.listen(clickButtons[i], 'click', function($event){ functionToCall($event.target); }); }; } } ngOnDestroy() { this.renderer.destroy(); } }
Я использовал Angular 6, для чего это стоит.
Ответ 4
в CSS:
.dropdown-menu {
pointer-events: none;
}
Это решит проблему с привязкой innerHTML (click).