如何在角度4中动态生成的元素上触发click事件?

时间:2018-01-05 10:01:23

标签: javascript html angular

我正在使用API​​ get调用从数据库中获取HTML代码并呈现html。

生成的HTML如下: -

<span (click)="triggerClick()" data-link-id="960" data-link="8" class="level_modal">individuals</span>

triggerClick()函数在ts文件中定义,但动态生成的html代码不会触发该函数。

2 个答案:

答案 0 :(得分:2)

的原因

它不会起作用。用于编写Angular模板的语言不是HTML。这是一个自定义的Angular语法,有意地看起来像HTML,可以更好地编写代码。然后将这些模板编译成高度优化的JavaScript函数。

在应用程序运行期间收到从API获得的字符串,这意味着Angular的编译器已经完成了它的工作(它编译了代码,这就是为什么你可以运行你的应用程序)。此时,Angular的编译器默认不再可用。将编译器包含在应用程序的最终捆绑包中是一个性能问题,因为编译器代码占用空间很大。这就是为什么AOT编译(提前)是为生产发布Angular应用程序的默认和推荐方式的原因。

解决方案

您的API根本不应返回HTML。单页面应用程序(SPA)背后的整个想法是供他们使用,以及与语言和平台无关的API。它只适用于数据,目前主要通过JSON表示法进行编码。这是API应该理解的唯一语言。

从我在此处发布的代码示例中我可以收集到的内容,您对此表单的数据感兴趣:

data-

创建一个API端点,以此形式返回数据,然后使用Angular循环数据并创建所需的模板。

link

当然,您可能不需要所有linkId属性。这是因为Angular应用程序应该关注模型。模型是用于创建模板的真实来源。如果您需要有关每个项目的其他信息(例如<table><div>),请将内存作为对象保留。不需要将其编码为HTML只是为了以后再读它。

答案 1 :(得分:1)

写作时

(click)="doSomething()"

你想说

  

单击此

时启动方法doSomething

但你实际上说的是

  

请Angular,编译此代码,以便当我点击它时,它会启动doSomething

因为您可能知道,您正在编写Typescript,而不是Javascript。因此,您的代码将被编译为服务,从而将其转换为

onclick="doSomething()"

但等等,还有更多

当您编译代码时,它实际上已经缩小并且已经变得丑化了。所以这会给你一些

的内容
onclick="a()"

因此,让你失去任何背后的逻辑。

那么解决方案是什么?

解决方案是将click事件绑定到全局函数。有两种方法可以做到这一点:

  • 组件中的功能(如果要使用组件中的逻辑,则使用它
  • 全局函数(如果您希望在多个组件中调用此函数,使用它

我将解释第一个用例,对于第二个用例,我将简要说明:创建一个JS文件作为资产,将您的函数放入其中,然后单击调用它。

对于第二个,它有点棘手。

首先,将ngZone注入到组件中:这允许您处理Angular之外的代码

constructor(private zone: NgZone) {}

然后,创建一个全局函数(我将使它成为Typescript和linting)

ngOnInit() {
  this.zone.run(() => {
    window['doSomething'] = () => {
      console.log('Look mom, I did something !');
    };
  });
}

在此之后,离开组件后删除该功能

ngOnDestroy() { delete(window['doSomething']); }

最后,从此

更改HTML
(click)="doSomething()"

到此

onclick="window.doSomething()"