首页 文章

在Angular2中,我需要在父组件中显示和隐藏子组件

提问于
浏览
1

In Angular2 hows best to show and hide child components?

我有 one parent componentthree child components .

默认情况下 onInit 需要隐藏所有子组件 . 并且 childComponentA 需要显示父组件中按钮的单击 .

The flow:

我在 childComponentA 中有一个按钮,需要在click上显示 childComponentB ,而childComponentB组件有一个需要显示 childComponentC 的按钮 . 就像表演和隐藏的流程一样 .

Hows best to do this?

Possible solution?

我正在考虑创建一个所有子组件订阅显示和隐藏的服务 . 但不确定它是否是最佳解决方案 .

Parent Component HTML:

<section>
   <button (click)="showChildComponentA()"></button>

   <childComponentA></childComponentA>
   <childComponentB></childComponentB>
   <childComponentC></childComponentC>
</section>

2 回答

  • 1

    如果你想保持你的代码干净和可维护,并且没有遍布整个地方的布尔标志,那么最好使用一个服务(可能称为 ToggleService )来处理切换和检查是否应该显示某些内容 .

    例如,这里有一个简单的 ToggleService ,它使您能够创建新项目,删除项目,并使用show / hide方法切换项目的可见性(请记住,下面没有任何测试,我只是简单地写了所有内容)这个问题的飞行 - 但这一切看似合乎逻辑,应该有效):

    @Injectable()
    export class ToggleService {
        toggleMap: {[uniqueKey: string]: any} = {};
    
        create(key: string) {
            this.toggleMap[key] = null;
        }
    
        remove(key: string) {
            delete this.toggleMap[key];
        }
    
        isShown(key: string): boolean {
            return this.toggleMap[key];
        }
    
        show(key: string) {
            this.toggleMap[key] = true;
        }
    
        hide(key: string) {
            this.toggleMap[key] = false;
        }
    }
    

    现在,在您的组件中,您可以利用该服务:

    @Component({...})
    export class MyComponent implements OnInit, OnDestroy {
        constructor(public toggleService: ToggleService) {}
    
        ngOnInit() {
            this.toggleService.create('componentOne');
            this.toggleService.create('componentTwo');
            this.toggleService.create('componentThree');
        }
    
        // Clean up when parent component is destroyed to save memory
        ngOnDestroy() {
            this.toggleService.remove('componentOne');
            this.toggleService.remove('componentTwo');
            this.toggleService.remove('componentThree');
        }
    }
    

    在模板中:

    <button (click)="toggleService.show('componentOne')">Show component 1</button>
    <button (click)="toggleService.show('componentTwo')">Show component 2</button>
    <button (click)="toggleService.show('componentThree')">Show component 3</button>
    
    <componentOne *ngIf="toggleService.isShown('componentOne')"></componentOne>
    <componentTwo *ngIf="toggleService.isShown('componentTwo')"></componentTwo>
    <componentThree *ngIf="toggleService.isShown('componentThree')"></componentThree>
    

    请记住,单击其中一个按钮不会隐藏另一个按钮 . 为此,您可能想要创建一个 toggle 方法,该方法将循环遍历服务中的整个 toggleMap 并使所有内容都为false,然后将一件事设置为true .

    我会留下最后一点作为锻炼给你;)

  • 2

    我会选择基于组件的设计 . 在我看来,事件驱动设计并不酷,因为很难跟踪哪个组件与哪个事件发布者进行交互 .

    Stackblitz example

    <button (click)="changeFlag(CompFlags.Comp1)">Show comp1 </button>
    <br>
    <comp1 *ngIf="checkState(CompFlags.Comp1)"  (clicked)="changeFlag(CompFlags.Comp2)"></comp1>
    <br>
    <comp2  *ngIf="checkState(CompFlags.Comp2)" (clicked)="changeFlag(CompFlags.Comp3)"></comp2>
    <br>
    <comp3  *ngIf="checkState(CompFlags.Comp3)"></comp3>
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html'
    }) 
    export class AppComponent  {
      CompFlags = CompFlags;
      state = CompFlags.None;
    
      changeFlag(flag:CompFlags){
        (this.state & flag) ? this.state &= ~flag : this.state |= flag;
      }
    
      checkState(flag:CompFlags){
        return !!(this.state & flag);
      }
    }
    
    export enum CompFlags{
      None = 0,
      Comp1 = 1 << 0,
      Comp2 = 1 << 1,
      Comp3 = 1 << 2
    }
    

相关问题