单击时切换相同类型的所有stencil.js组件

时间:2019-11-07 18:30:03

标签: javascript typescript stenciljs tsx

我正在创建一个工具栏,该工具栏将用于文本编辑。

使用以下代码创建工具栏中的每个项目:

public override void CollectObservations()
{
    //internal info
    AddVectorObs(gameObject.transform.rotation.z);
    AddVectorObs(gameObject.transform.position);

    Vector3 externalInfo1 = ExternalInfoGetter.StaticGetInfo1();
    AddVectorObs(externalInfo1);

    float externalInfo2 = ExternalInfoGetter.StaticGetInfo2();
    AddVectorObs(externalInfo2);
}

这可以按预期工作,但是,我希望在单击一个项目时关闭所有其他下拉菜单,因此基本上,'this.toggle'需要应用于所有非活动的下拉菜单。我该怎么办?

3 个答案:

答案 0 :(得分:0)

因此,想法是将addEventListener应用于文档以及组件本身(“主机”-下拉列表)。为此,您可以使用componentdidload之类的生命周期钩子。

import {Component, h, Prop, Event, EventEmitter} from '@stencil/core';

@Component({
  tag: 'spa-toolbar-item',
  styleUrl: 'spa-toolbar-item.scss',
})

export class spaToolbarItem {
  @Prop({reflectToAttr: true, mutable: true}) toggle: boolean = false;
  @Prop({reflectToAttr: true}) type: string;
  @Event() onToggle: EventEmitter;

private hostElement;
private buttonElement;
  closeDropdown(){
    this.toggle = false;
  }
  toggleComponent(): void {
    this.toggle = !this.toggle;
    this.onToggle.emit({visible: this.toggle});
  }

render() {
 return 
 <Host ref={(el) => this.hostElement = el}>
   //everything you had before in the return value
 </Host>
}

 componentDidLoad(){
  document.addEventListener("click", ()=>{this.clickManager("document");}, true)
  this.hostElement.addEventListener("click", ()=>{this.clickManager("dropdown");}, true)
 }

 private clickManager(identifier){
   if(identifier == "dropdown"){
     //the clicked dropdown -> active dropdown
     this.toggleComponent();
     return;
   }
   //all non active Dropdowns
   this.closeDropdown();
 }

}

如您所见,我们有两个事件正在调用clickManager。第一个是文档,第二个是您单击的下拉列表。当然,您必须删除按钮上的onclick事件,但是此代码无法正常工作。现在,您可以决定如果单击下拉菜单会发生什么情况,以及所有非活动的下拉菜单会发生什么情况。

这是基本概念,可以根据需要随时进行调整和更改。

答案 1 :(得分:0)

感谢Christian,我最终在下面使用了此解决方案。

import {Component, h, Prop, Host, Element} from '@stencil/core';

@Component({
  tag: 'spa-toolbar-item',
  styleUrl: 'spa-toolbar-item.scss',
})

export class spaToolbarItem {
  @Prop({reflectToAttr: true, mutable: true}) isOpen: string = 'false';
  @Prop({reflectToAttr: true}) type: string;
  @Element() el: HTMLElement;

  openDropdown() {
    function closeDropdown() {
      let dropdowns = document.querySelectorAll('spa-toolbar-item[is-open]');
      dropdowns.forEach(item => {
        item.setAttribute('is-open', 'false')
      });
    }

    if (this.el.getAttribute('is-open') == 'true') {
      closeDropdown();
      return
    }

    if (this.el.getAttribute('is-open') == 'false') {
      closeDropdown();
      this.el.setAttribute('is-open', 'true')
    }
  }

  render() {
    return (
      <Host>
        <button onClick={this.openDropdown.bind(this)}>
          <slot/>
        </button>
        <div class={this.type}>
          {this.type == 'font'
            ? <div>
              <span class="arial">Arial</span>
              <span class="georgia">Georgia</span>
              <span class="palatino">Palatino</span>
              <span class="tahoma">Tahoma</span>
              <span class="times">Times New Roman</span>
              <span class="helvetica">Helvetica</span>
              <span class="courier">Courier New</span>
              <span class="lucida">Lucida Sans Typewriter</span>
              <span class="verdana">Verdana</span>
            </div>
            : null}
        </div>
      </Host>
    )
  }
}

答案 2 :(得分:-1)

使用纯JavaScript可以做什么,使用is-active类遍历所有元素,并将每个元素的toggle属性设置为0(或您执行的方式)

示例:

new Array(document.getElementsByClassName('is-active')).forEach(function(e){/*Set toggle property to 0*/});

这是什么,用is-active搜索所有元素,遍历它们,并设置一个函数,在此函数中,参数e等于当前元素,您可以在此处设置属性。