【问题标题】:Access Parent component from Child component. Use service? What about @ContentChildren?从子组件访问父组件。使用服务? @ContentChildren 呢?
【发布时间】:2019-06-21 19:16:41
【问题描述】:

我创建了一个 Angular 7 手风琴组件SlackBlitz Example

export class AccordionComponent {

  @ContentChildren(PanelComponent) panels: QueryList<PanelComponent>;

  ngAfterContentInit() {
    this.panels.forEach((panel) => {panel.active = false;});
  }

} 

PanelComponent 如下:

export class PanelComponent {

  @Input() active: boolean;
  @Input() title: string;

  toggle() {
    this.active = !this.active;
  }

}

手风琴正在工作,但我需要在打开新面板时关闭所有面板。

我认为这可以通过两种方式完成:

  1. 在 PanelComponent 中能够访问 AccordionComponent 上的方法。
    该方法将设置一个面板处于活动状态,其余的处于非活动状态。

    我不知道如何从子组件(面板)访问父组件(手风琴)

  2. 使用包含面板的 AccordionService:

    panels: PanelComponent[] = [];   
    

    然后在 Accordion 和 Panel 中注入这个服务。

    这似乎合乎逻辑,但后来我停止使用 @ContentChildren(PanelComponent)。

    从某种意义上说,这打破了 Accordion 和 Panel 之间的关系。

我应该使用哪种解决方案?还是别的?

我的 2 个解决方案是否遗漏了什么(我不知道如何实施解决方案 1)。

【问题讨论】:

    标签: angular angular6 angular7 angular-components


    【解决方案1】:

    关于第1点,你可以注入父组件,如下:

    constructor(
      @Inject(forwardRef(() => AccordionComponent)) private accordion: AccordionComponent, 
      ...)
    

    使用服务也可以,但对于这种简单的情况,恕我直言,它似乎需要更多的工作。

    【讨论】:

      【解决方案2】:

      您可以轻松地使用事件发射器来解决您的目的。

      See this stackblitz

      对您的代码所做的更改:

      panel.component.ts

       @Input() activate: string;
        @Input() title: string;
        @Output() closeOtherPanels: EventEmitter<string> = new EventEmitter();
      
        active : boolean = false;
      
      ngOnChanges(changes : SimpleChanges){
        if(changes.activate){
          this.active = this.activate == this.title;
        }
      }
      
        toggle() {
          this.active = !this.active;
          if(this.active){
            this.closeOtherPanels.emit(this.title);
          }
        }    
      

      app.component.ts

      export class AppComponent  {
        activeTitle : string="";
        name = 'Angular';
      
        closeOtherPanels(value){
          this.activeTitle=value;
        }
      }
      

      app.component.html

      <accordion> <panel title="Panel 1 title" [activate]="activeTitle" (closeOtherPanels)="closeOtherPanels($event)">Panel 1 content</panel> <panel title="Panel 2 title" [activate]="activeTitle" (closeOtherPanels)="closeOtherPanels($event)">Panel 2 content</panel> <panel title="Panel 3 title" [activate]="activeTitle" (closeOtherPanels)="closeOtherPanels($event)">Panel 3 content</panel> <panel title="Panel 4 title" [activate]="activeTitle" (closeOtherPanels)="closeOtherPanels($event)">Panel 4 content</panel> </accordion>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-08
        • 1970-01-01
        • 2020-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-08
        • 1970-01-01
        相关资源
        最近更新 更多