【问题标题】:@Input() selected appearing false on first click (Angular)@Input() 选择在第一次单击时出现错误(Angular)
【发布时间】:2023-03-27 07:51:01
【问题描述】:

我正在构建手风琴组件。我想要的行为是一次只能打开一个手风琴(总共三个)。换句话说,当单击当前打开的手风琴之外的任何手风琴时,任何打开的手风琴都应该折叠。

现在,我可以打开/关闭这些手风琴,但我无法弄清楚如何“选择”它们以应用“折叠”类(如果当前未选择)。我的选择输入在第一次点击时是错误的(它在 Augury 中以其他方式显示)。

手风琴组.component.ts

import { AccordionComponent } from './../accordion/accordion.component';
import { Component, Input  } from '@angular/core';


@Component({
  selector: 'app-accordion-group',
  templateUrl: './accordion-group.component.html',
  styleUrls: ['./accordion-group.component.css']
})
export class AccordionGroupComponent {
  @Input() measures;
  selected

  select(i){
    this.selected = i;
  }
}

手风琴组.component.html

<app-accordion
*ngFor="let item of items; let i = index"
[item]="item"
[selected]="i === selected"
(click)="select(i)">
</app-accordion>

accordion.component.ts

import { Component, Input } from "@angular/core";

@Component({
  selector: "app-accordion",
  templateUrl: "./accordion.component.html",
  styleUrls: ["./accordion.component.css"]
})
export class AccordionComponent {
  @Input() item;
  @Input() index;
  @Input() selected //this needs to receive true on selected component on click


  expand: string = "";
  isOpen = false;

  handleExpansion() {
    console.log(this.selected) //logs false on first click
    this.isOpen = !this.isOpen;

    this.isOpen ? (this.expand = "expand") : (this.expand = "collapse");
  }
}

accordion.component.html

<div
(click)="handleExpansion()"
class="accordion noHighlight {{expand}}">
</div>

【问题讨论】:

  • AccordionComponent 中的点击处理程序将在AccordionGroupComponent 中的点击处理程序之前执行,因为事件会冒泡。这是预期的行为。您是否考虑过监听selected 属性的更改并删除AccordianComponent 中的点击处理程序?
  • 我该怎么做呢?将点击处理程序移动到 Accordion 组件?如果当前未选择,我将如何与每个手风琴兄弟交流它应该关闭?

标签: angular typescript


【解决方案1】:

如上所述,您遇到这种情况的原因是浏览器 DOM 事件冒泡。因此,AccordionComponent 中的点击处理程序将在AccordionGroupComponent 中的点击处理程序之前执行。

有很多方法可以完成你想做的事情,所以我把a quick Plunker for you 和一种方法放在一起。

它的要点是由小组决定展开哪个手风琴(如果有的话):

@Component({
    selector: 'app-accordion-group',
    template: `
        <app-accordion *ngFor="let accordion of accordions" [title]="accordion.title"
            [isExpanded]="accordion === expandedAccordion"
            (expandClick)="processExpandClick(accordion, $event)">
            <p>{{ accordion.description }}</p>
        </app-accordion>
    `
})
export class AccordionGroupComponent {
    @Input() accordions: Accordion[];

    expandedAccordion: Accordion = null;

    processExpandClick(accordion: Accordion, isExpanded: boolean) {
        this.expandedAccordion = isExpanded ? accordion : null;
    }
}

当发生展开/折叠事件时,手风琴会发出事件,允许组确定要展开/折叠的内容:

@Component({
    selector: "app-accordion",
    template: `
        <div class="accordion" [class.expanded]="isExpanded">
            <div (click)="handleClick()">
                <span *ngIf="!isExpanded">+</span>
                <span *ngIf="isExpanded">-</span>
                {{ title }}
            </div>
            <div class="accordion__content">
                <ng-content></ng-content>
            </div>
        </div>
    `,
    styles: [`
        .accordion__content {
            height: 0;
            overflow: hidden;
        }

        .expanded .accordion__content {
            height: auto;
        }
    `]
})
export class AccordionComponent {
    @Input() title;
    @Input() isExpanded = false;
    @Output() expandClick = new EventEmitter<boolean>();

    handleClick() {
        this.expandClick.emit(!this.isExpanded);
    }
}

【讨论】:

  • 感谢您提供示例,这对我的问题有所帮助。
  • 如何在首次点击时仅应用“折叠”类?
  • 我不明白你在问什么。你能说得更具体点吗?
  • 当 isExpanded 为 false 时,我会应用“折叠”动画。因为它在加载时默认为 false,所以动画会导致所有手风琴折叠 - 或者在您首次加载页面时自动从打开变为关闭。
  • 好的。是的,就像我说的,有很多方法可以处理这个问题。我的示例中的假设是最多会扩展一个。听起来你想要一个可以打开它们的情况。在这种情况下,您可以保留所有手风琴的 isExpanded 状态并默认将它们全部展开。这是一个更新的 Plunker,显示了一种快速的方法:plnkr.co/edit/WTMg5g3UWMM04x40hWEW?p=preview
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
  • 2017-08-21
相关资源
最近更新 更多