网站搜索

html - Angular overlaypanel 每次都会保持打开


我创建了一个类似 p-overlaypanel 的 Angular 组件,但它在我点击每个项目时都会保持打开状态。我希望如果我点击另一个覆盖面板,上一个被点击的应该被隐藏,我只想点击一个并显示,而不是它们全部显示。下面你可以在 stackblitz 中找到代码。

https://stackblitz.com/edit/angular-yrsyt6?file=src/app/app.component.ts

这是代码

<div class="dropdown">

  <div  class="body">
    <ng-content select="[body]"></ng-content>
  </div>

  <div *ngIf="active" class="popup">
    <ng-content select="[popup]"></ng-content>
  </div>

</div>
.dropdown {
  position: relative;
  display: inline-block;
}

.popup {
  display: block;
  position: absolute;
  z-index: 1000;
}

export class OverlaypanelComponent implements OnInit {

  active = false;

  constructor() {

  }

  ngOnInit() {

  }
  @HostListener('document:click', ['$event']) clickedOutside($event) {
    this.active = false;
  }

  toggle($event) {
    $event.preventDefault();
    $event.stopPropagation();
    this.active = !this.active;
  }

  close() {
    this.active = false;
  }

}

答案#1

为了做到这一点,你将需要让子组件(面板)以某种方式向父组件传达它已经打开的信息,而关闭其他面板将是父组件的责任。为此,active 属性也应作为一个 Input 绑定。这意味着至少需要增加三件事情之一:一个 Input 绑定用于确定面板是否处于激活状态,一个 Input 绑定用于标识面板,以及一个 Output 绑定用于发出面板正在显示的信号:

@Input() active = false;
@Output() activeChanged = new EventEmitter();
@Input() index;

toggle($event) {
  $event.preventDefault();
  $event.stopPropagation();
  this.active = !this.active;
  if (this.active) {
    this.activeChanged.emit(this.index);
  }
}

现在你的父组件将必须绑定到这些属性,并且还要响应 Output 来更改其他面板的绑定。这应该很容易通过使用数组或一些可以用来包含面板的迭代数据结构来实现。

  panels = new Array(4).fill({ active: false });

  closeOtherPopups(index) {
    this.panels = this.panels.map((panel, idx) => (
      { active: idx === index }
    ));
  }

在这里查看实际效果:https://stackblitz.com/edit/angular-u96ssk?file=src/app/app.component.ts