ChatGPT解决这个技术问题 Extra ChatGPT

Angular 2: Component Interaction, optional input parameters

I have an implementation where parent wants to pass certain data to child component via the use of @Input parameter available at the child component. However, this data transfer is a optional thing and the parent may or may not pass it as per the requirement. Is it possible to have optional input parameters in a component. I have described a scenario below:

 <parent>
    <child [showName]="true"></child> //passing parameter
    <child></child> //not willing to passing any parameter
</parent>



//child component definition
@Component {
    selector:'app-child',
    template:`<h1>Hi Children!</h1>
          <span *ngIf="showName">Alex!</span>`
}


export class child {

    @Input showName: boolean;

    constructor() { }

}
Yes you can have optional input, check in ngAfterViewInit lifecycle event if the input is initialized or not
Thanks @galvan , It Worked!

A
Aravind

You can use the ( ? ) operator as below

import {Component,Input} from '@angular/core';
@Component({
    selector:'child',
    template:`<h1>Hi Children!</h1>
          <span *ngIf="showName">Alex!</span>`
})


export class ChildComponent {

    @Input() showName?: boolean;

    constructor() { }

}

The parent component that uses the child component will be as

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <child [showName]="true"></child>
      <child ></child>
    </div>
  `,
})
export class App {
  name:string;
  constructor() {
    this.name = 'Angular2'
  }
}

LIVE DEMO


This should be the answer. Also works with default values @Input() showName?: boolean = true;
I was wondering , is there any difference vs the regular @Input() showName: boolean; ? and then check if not null ? I mean - what is the difference ?
@RoyiNamir Most importantly I would say, it is a form of documentation. By placing the ? or not you can communicate whether your component can deal with this input being undefined or not. Also, I think it is recognized by the strictNullChecks compiler option christianliebel.com/2017/05/…
@MatthiasTylkowski if you set a default value then it doesn't make sense to make it optional, since it will always be set to something.
@MatthiasTylkowski Optional means that showName property might possibly not exist, yet setting it to true by default means it will always exist, so there's no point making it optional. (null is irrelevant here, a property set to null still exists. optional only relates to defined or undefined.) - optional here doesn't refer to whether or not the input has to be passed in (inputs are optional by default) but whether the property showName has to exist on the class.
A
Arnaud P

Input values are optional by default. Your code will fail only when it tries to access properties of inputs that are not actually passed (since those inputs are undefined).

You can implement OnChanges or make the input a setter instead of a property to get your code executed when a value is actually passed.

export class child {

    @Input set showName(value: boolean) {
      this._showName = value;
      doSomethingWhenShowNameIsPassed(value);
    }

    constructor() { }
}

Check @galvan's comment, it seems to be a better solution.
Why do you think it's better? When the parent has to make a request to the server and only then passes the value to the child, then this might be quite some time after ngAfterViewInit() was called. ngAfterViewInit() might work in your concrete case but in general I wouldn't recommend it.
You mean to say, If I am changing the values on the fly on client side? And as explained by you, should i call the setter method in the child directive?
You don't need to call the setter but if you have <child [showName]="propOnParent"> and propOnParent is initialized after some async call completes, then Angular updates the showName input in <child> or in case when it's a setter, calls the setter with the updated value.
Also if you just care about statically bound valus like true in your question, ngOnInit() is the more common lifecycle hook than ngAfterViewChecked().
A
Alexander Ciesielski

You have two options here.

1) You can use an *ngIf on the child in case the child does not need to be displayed when its Input is empty.

 <parent>
    <child *ngIf="true" [showName]="true"></child> //passing parameter
    <child></child> //not willing to passing any parameter
</parent>

2) In case the child should get displayed without any input, you can use a modified setter to check for the presence of input variables`

In the child.ts:

private _optionalObject: any;
@Input()
set optionalObject(optionalObject: any) {
    if(optionalObject) this._optionalObject = optionalObject;
}
get optionalObject() { return this._optionalObject; }

Check @galvan's comment, it seems to be a better solution.