Angular 2 innerHTML (click) binding

匿名 (未验证) 提交于 2019-12-03 01:48:02

问题:

I had such a large html menu that I decided to binding to be able to make several submenu dropdown and avoid html code duplication. Parent > child (which is parent too) > child...

For the context : In ng2_msList/msList.components.ts, ColumnsManagements.ts is imported as this.ColumnsManagementInstance. The innerHTML menu is displayed properly, in ng2_msList/pages/list.html :

 

With (in a very simplified version of my code) : (Thanks to this 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 :       //       [...]      return htmlcolumnsmenu; } 

BUT (click)="msList.ColumnsManagementInstance.toogleColumn(column)" (previously in the html content) is not working anymore. It's writing in the view as simple text in tag (before the innerHtml it was not displayed).

I can't reach a way to make it works again. I test multiple ways to call the function or as I found in web links as on the Ang Doc Section, here for example. These examples call a function which is set in the same file/context very easily (click)="MyAction()" but with my context I can't get a way to call it properly.

The app architecture is maybe be not as Angular2 click call would expect.

回答1:

That's by design. Angular doesn't process HTML added by [innerHTML]="..." (except sanitization) in any way. It just passes it to the browser and that's it.

If you want to add HTML dynamically that contains bindings you need to wrap it in a Angular2 component, then you can add it using for example ViewContainerRef.createComponent()

For a full example see Angular 2 dynamic tabs with user-click chosen components

A less Angulary way would be to inject ElementRef, accessing the added HTML using

elementRef.nativeElement.querySelector('a').addEventListener(...) 


回答2:

It may be too late but let me hope that is going to help someone.

Since you want click binding (and probably other bindings) it would be better to skip using [innerHTML]="..." and create an inner component to which you pass the data via @Input() annotation.

Concretely, image you have a component called BaseComponent where you set some HTML code to a variable htmlData :

let htmlData  = '......' 

Then in BaseComponent's html file you bind it like below:

...
...

Instead of doing this, you create 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's Html file:

...... 

Now in BaseComponent's Html file:

...


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!