从兄弟组件更改组件的公共变量

时间:2016-09-13 20:39:21

标签: angular typescript public

我有两个从我的app.component设置的兄弟组件:

<my-a></my-a>
<my-b></my-b>

<my-a>的可见性由其中的公共变量控制:

@Component({
  moduleId: module.id,
  selector: 'my-a',
  templateUrl: `<div *ngIf="visible">Hello World</div>`
})

export class MyAComponent {
    public visible = false;
}

点击visible中的元素后,我想更改<my-b>的值:

@Component({
  moduleId: module.id,
  selector: 'my-b',
  templateUrl: `<div (click)="onClick()">Click Me</div>`
})

export class MyBComponent {
    onClick() {
        // stuff here
    }
}

如何在visible = true <my-a><my-b>设置app.component这个逻辑是否应该在父@Component({ moduleId: module.id, selector: 'my-b', templateUrl: `<div (click)="onClick('my-a')"></div>` }) export class MyBComponent { onClick(element) { $(element).show(); // or hide() or toggle() or whatever } } 中?

修改

感谢您的回答。我在几行jQuery中实现了一些工作正常:

! /my/precompiled/header/file.h.gch

如果我们需要更多元素,而不是向每个组件添加发射器和输入,使用jQuery可以轻松扩展。

我只是担心在Angular2中使用jQuery是不好的做法?

2 个答案:

答案 0 :(得分:2)

有几种方法可以做到这一点。 IMO最简单的将使用EventEmitter和Input。

组件A:

@Component({
  moduleId: module.id,
  selector: 'my-a',
  templateUrl: `<div *ngIf="visible">Hello World</div>`
})

export class MyAComponent {
    // listen for variable passed by parent
    @Input() visible;
}

组件B:

@Component({
  moduleId: module.id,
  selector: 'my-b',
  templateUrl: `<div (click)="onClick()">Click Me</div>`
})

export class MyBComponent {
    // creating EventEmitter to emit when onClick is called
    @Output() visible = new EventEmitter();
    onClick() {
        this.visible.emit();
    }
}

在父组件中:

@Component({
  moduleId: module.id,
  selector: 'parent',
  // passing variable visible to MyAComponent and listening for (onClick) from MyBComponent
  templateUrl: `<my-a [visible]="visible"></my-a>
                <my-b (onClick)="changeVisible()"></my-b>`
})

export class ParentComponent{
    private visible: boolean = false;
    // when MyBComponent emits event change visible value (which is then passed to MyAComponent)
    changeVisible() {
    if (this.visible === false) {
    this.visible = true;
    } else {
        this.visible = false;
        }      
    }
}

在更高级的情况下,您应该使用共享服务。

答案 1 :(得分:1)

逻辑分为三个部分,但是,它以父app.component为中心。您将其视为具体任务:

  1. 需要访问外部来源以更改可见性。您将使用Input属性
  2. 执行此操作
  3. 有一个按钮,此按钮的目的是触发对其他组件的某些操作。所以它应该有一个Output属性(这是一个EventEmitter)
  4. 然后父对象可以绑定到“输出”以设置一个绑定到输入的变量。
  5. MyAComponent

    中的输入属性
    import { Component, Input } from '@angular/core';
    @Component({
      moduleId: module.id,
      selector: 'my-a',
      template: `<div *ngIf="visible">Hello World</div>`
    })
    export class MyAComponent {
        @Input() visible: boolean = false;
    }
    

    父组件用于设置它的HTML将是:

    <my-a [visible]="aVisibility"></my-a>
    

    MyBComponent

    中的输出属性
    import { Component, Output, EventEmitter } from '@angular/core';
    @Component({
      moduleId: module.id,
      selector: 'my-b',
      template: `<div (click)="onClick()">Click Me</div>`
    })
    export class MyBComponent {
        @Output() makeVisible: EventEmitter<void> = new EventEmitter<void>();
    
        onClick() {
            this.makeVisible.emit();
        }
    }
    

    想要收听更改的父组件的HTML将如下所示:

    <my-b (makeVisible)="makeAVisible()"></myb>
    

    使用父级将其绑定在一起

    import { component } from '@angular/core';
    @Component({
        moduleId: module.id,
        selector: my-app,
        template: `
          <my-a [visible]="aVisibility"></my-a>
          <my-b (makeVisible)="makeAVisible()"></myb>
        `
    })
    export class MyApp {
        private aVisibility:boolean = false;
    
        makeAVisible() : void {
            this.aVisibility = true;
        }
    }
    

    注释

    这是所有未经测试的代码,因此可能存在拼写错误。另外,如果两个组件之间的通信很复杂,那么你应该更喜欢在两者之间共享一个服务,但对于像这样简单的事情,我认为通过父组件是可以的。