1

I have a parent component with the following directive <child-component [hidden]="!visible"></child-component>. Initially, the child component associated to this directive is hidden and after some event, I want to make it visible, so I'm using a button <button (click)="showMe()">Show child</button> in the parent component to change this property.

export class App {
  constructor() {
    this.visible = false;
  }

  showMe() {
    this.visible = true;
  }
}

The problem is that, once this shows the child component, I need to provide a button <button (click)="hideMe()">Hide</button> in the child component to hide it again:

export class ChildComponent {
  constructor(private _element: ElementRef, private _renderer: Renderer) {}

  hideMe() {
    let el = this._element.nativeElement);
    this._renderer.setElementStyle(el, 'visibility', 'hidden');
  }
}

I'm not sure about this part but at least it works. Now, what happens if I want to change the property hidden of the child-component directive again? Calling showMe() doesn't work, presumably because of some kind of precedence in the applied styles.

What is the correct way to do this?

Demo: First click on 'Show child', then click on 'Hide' and then try to click on 'Show child' again. The last button clicked doesn't work.

Thanks

1 Answer 1

3

Not sure this is the approach that you want, but I think it behaves like described:

@Component({
  selector: 'child-component',
  providers: [],
  host: {'[hidden]': 'hidden'},
  template: `
    <div>
      This is the child
    </div>
    <button (click)="hidden=true">Hide</button>
  `,
})
export class ChildComponent {
  @Input() hidden:boolean = false;
}
  <child-component #child [hidden]="true"></child-component>
  <button (click)="child.hidden=false">Show child</button>

Plunker example

The problem in your example is that the hidden property and visibility: hidden get conflicting values.

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you. After reading the documentation, I think I understand what you are doing. The only problem is that I can't initiate the child component as hidden without breaking something else. Do you have a solution in that case?
I updated my answer. Just adding [hidden]="true" should make it initially hidden .
Of course :-) Thanks. By the way, is this the most straightforward way to accomplish communication between child and parent components?
Instead of a referring to a template variable #child you could refer to a field in parent (like visible in your example). That's the more common way, but in this example just using a direct reference in the template seemed more straight-forward.
Yes inputs: ["hidden"] ... input:boolean = false; is the same as @Input() input:boolean = false; just a different way of expressing it. You need the input to be able to pass values like <child-component [hidden]="false">`. We could use a different name for the input but I didn't see a reason to invent a new one.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.