javascript - 从 StencilJS 到 Angular 的事件发射器

标签 javascript angular stenciljs

我需要监听子组件触发的事件。就我而言,我有一个用 stencil v1 制作的“选项卡”组件,具有以下结构...

abc-tabs.tsx

import { Component, h, Listen, Element, State, Event, Method, EventEmitter } from '@stencil/core';

@Component({
  tag: 'abc-tabs'
})
export class AepTabs {
  @Element() tabs: HTMLElement;
  @State() initIndex: number = 0;
  @Event() tabClick: EventEmitter; // <---------- HERE
  private tabsElements;
  private tabsElementList: Array<any> = [];
  private tabTitleElements: any;

  componentWillLoad() {
    this.createTabsTitles(this.tabs.querySelectorAll('abc-tab'));
  }

  componentDidLoad() {
    this.addTitleEvents();
  }

  addTitleEvents() {
    this.tabTitleElements = this.tabs.getElementsByClassName('tab-title');
    [].forEach.call(this.tabTitleElements, (tab, pos) => {
      tab.addEventListener('click', () => {
        this.tabClick.emit(tab);
        this.activeTabs(pos);
      });
    });
    this.activeTabs(this.initIndex);
  }

  createTabsTitles(tabsList: NodeList) {
    this.tabsElements = tabsList;
    [].forEach.call(this.tabsElements, tab => {
      this.tabsElementList.push(
        <div class="tab-title" data-automation={tab.titletab.toString().toLowerCase()}>
          <span>{tab.titletab}</span>
        </div>
      );
    });
  }

  @Method()
  activeTabs(index: number) {
    this.tabTitleElements = this.tabs.getElementsByClassName('tab-title');
    [].forEach.call(this.tabTitleElements, (tab, pos) => {
      if (index === pos) {
        tab.classList.add('active');
        tab.classList.remove('inactive');
      } else {
        tab.classList.remove('active');
        tab.classList.add('inactive');
      }
    });

    [].forEach.call(this.tabsElements, (tab, pos) => {
      if (index === pos) {
        tab.classList.add('active');
        tab.classList.remove('inactive');
      } else {
        tab.classList.remove('active');
        tab.classList.add('inactive');
      }
    });
  }

  // HERE --------------------------------------------------------
  @Listen('tabClick') 
  clicktabHandler(event: CustomEvent) {
    this.activeTabs(event.detail);
  }
  // HERE --------------------------------------------------------

  render() {
    return (
      <div>
        <nav>{this.tabsElementList}</nav>
        <div>
          <div>
            <slot />
          </div>
        </div>
      </div>
    );
  }
}

因此,在我的 Angular 项目中,我使用了模板组件。

detail.component.html

<abc-tabs>
  <abc-tab titletab="My first tab">
    <!-- content here -->
  </abc-tab>
  <abc-tab titletab="My second tab" >
    <!-- content here -->
  </abc-tab>
</abc-tabs>

一切都很完美,但现在我需要@Listen(在 Angular 中)单击某些选项卡时触发的事件,所以我在我的detail.component.ts 类中执行此操作:

detail.component.ts

import { Component, OnInit } from '@angular/core';
import { Listen, Watch } from '@stencil/core';

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html'
})
export class DetailComponent implements OnInit {
  constructor() {}

  ngOnInit() {}

  @Listen('tabClick') // <--- ERROR HERE
  clicktabHandler(event: CustomEvent) {
    console.log('has clicked!!!! ', event.detail);
  }
}

但是,它在 detail.component.ts 中抛出错误:

ERROR Error: Uncaught (in promise): TypeError: Object(...) is not a function
TypeError: Object(...) is not a function

即使我从 @stencil/core 导入 @Listen,Angular 也看不到“clicktab”。

有什么提示吗?

最佳答案

您应该使用@HostListener('tabClick')而不是@Listen('tabClick')

关于javascript - 从 StencilJS 到 Angular 的事件发射器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59002660/

相关文章:

javascript - 如何重复通过ajax检索数据的文本字段

ionic-framework - 如何从 Ionic2 中的 ionic 输入获取包装输入?

angular - Angular2 中的默认属性值 - 构造函数还是内联?

javascript - stenciljs 观察装饰器未触发

javascript - 将多行文本边框作为更多文本中的一个 block

javascript - Spotify 如何屏蔽音频 URL 并阻止下载歌曲 mp3

javascript - 格式化 JavaScript 标签的正确方法是什么?

angular - Ionic 4 自定义组件

html - StencilJS:可选的 <slot/> 元素在 IE11/Edge 中不起作用

slots - 如何确定插槽中子项的数量