【问题标题】:Angular2 - catch/subscribe to (click) event in dynamically added HTMLAngular2 - 在动态添加的 HTML 中捕获/订阅(单击)事件
【发布时间】:2016-07-07 02:52:15
【问题描述】:

我正在尝试将包含 (click) 事件的字符串注入 Angular2 模板。在加载 DOM 之后,该字符串会从后端动态检索。 Angular 无法识别注入的(click) 事件也就不足为奇了。

示例模板:

<div [innerHTML]="test"></div>

后端给出的示例字符串:

var test = "When ready, <span (click)=\"itemClick($event)\">click me</span>."

Angular 组件中的示例函数调用:

itemClick(event) {
   debugger;
}


我的下一个猜测是尝试让 Angular 订阅或捕获一个普通的 javascript 事件,因此字符串将是:
var test = "When ready, <span onClick=\"itemClick($event)\">click me</span>."

果然,我收到了一个错误 itemClick is not defined,所以我知道它正在寻找那个 javascript 函数。

所以问题:我怎样才能让 Angular2 订阅这个事件或函数?

【问题讨论】:

    标签: javascript events try-catch angular subscribe


    【解决方案1】:

    仅在组件模板中的静态 HTML 中支持声明式事件绑定。
    如果要订阅动态添加的元素的事件,则需要强制执行。

    elementRef.nativeElement.querySelector(...).addEventListener(...)
    

    或类似的。

    如果你想要 WebWorker 安全,你可以注入 Renderer

    constructor(private elementRef:ElementRef, private renderer:Renderer) {}
    

    改为使用

    this.renderer.listen(this.elementRef.nativeElement, 'click', (event) => { handleClick(event);});
    

    注册一个事件处理程序。

    另见Dynamically add event listener in Angular 2

    【讨论】:

    • 我想补充一点,由于上述代码是在组件内部执行的(正如 Günter 使用 ElementRef 和/或 Renderer 的事实所证明的那样),它是在 Angular 区域内执行的,因此在 click 事件处理程序触发后,Angular 更改检测将始终运行(根据需要)。 (如果您将事件处理程序附加到 Angular 之外,它将无法按预期工作。)
    • 如果我们使用addEventListener()listen(),是否需要注销ngOnDestroy()中的监听器?
    • 我认为 - 是的,但我不确定这一点。通常,如果您强制请求资源,则为了安全起见,您有责任释放。
    • 显然Renderer.listen() 将返回一个删除监听器的函数(这很方便)。请参阅 Eric 的答案以获取示例:stackoverflow.com/a/35082441/215945
    • 谢谢!我遇到了完全相同的问题,我不清楚如何在特定范围内为单击事件添加侦听器。例如问题中提出的那个。
    【解决方案2】:

    我在我的服务 中导入 ElementRef 时遇到问题,并且不想在那里传递 Renderer 引用。该服务是关于显示“正在加载...”对话框,在 3 秒后附加 动态关闭按钮。我找到了如何使用 jQuery 为这个按钮添加点击事件的解决方案。希望这对某人有所帮助。

    (1) 将 jQuery 添加到 Angular 2 index.html 文件中

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    

    (2) 声明 $

    declare var $: any;
    

    (3) 使用jQuery 这是我的服务中的一段代码:

     public async present() {
        this.isLoading = true;
        return await this.loadingController.create({message: 'Loading...'}).then(a => {
          a.present().then(() => {
            setTimeout(() => {
              a.message += '<ion-icon name="close-circle" class="alert-cancel-button"></ion-icon>';
    
    
              // Here starts jQuery usage
              $(a).click((clickedObject) => {
                if ($(clickedObject.target).hasClass('alert-cancel-button')) {
                  this.dismiss();
                }
              });
    
    
            }, 3000);
          });
        });
      }
    
      public async dismiss() {
        return await this.loadingController.dismiss();
      }
    
    • 顺便说一句,$('alert-cancel-button').click(() =&gt; this.dismiss()) 没用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-20
      • 2023-04-11
      • 2017-08-15
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多