ttugates
ttugates

Reputation: 6291

How to implement *ngIf/disabled on element of child component, predicated on parent component

Parent component markup:

<full-screen-dialog-header (onClickPrimaryAction)="onClickSaveCustomer()"
  (primaryActionDisabled)="*ngIf=customerFormGroup.enabled && !customerFormGroup.valid">
</full-screen-dialog-header>

Child component:

export class FullScreenDialogHeaderComponent {

  @Input() primaryActionDisabled: Observable<boolean>;
  @Output() onClickPrimaryAction = new EventEmitter();

  public onClickPrimaryActionEvent($event) {
    this.onClickPrimaryAction.emit($event);
  }
}

Child markup

...
<button mat-button (click)="onClickPrimaryActionEvent($event)" 
[disabled]="primaryActionDisabled">{{primaryActionText}}</button>
...

I am trying to get @Input() primaryActionDisabled: Observable<boolean> to work.

My issue and expected behavior is:

Upvotes: 0

Views: 2450

Answers (1)

Martin Ad&#225;mek
Martin Ad&#225;mek

Reputation: 18399

First of all, when using @Input decorator, you should use [primaryActionDisabled] binding.

Then you need to pass observable there, not expression:

// in parent controller
primaryActionDisabled$ = new BehaviorSubject<boolean>(true); // disabled by default

// in parent template
<full-screen-dialog-header 
    (onClickPrimaryAction)="onClickSaveCustomer()"
    [primaryActionDisabled]="primaryActionDisabled$">
</full-screen-dialog-header>

Then you will need to call primaryActionDisabled$.next(newBoolValue); every time the value should change (so every time the expression customerFormGroup.enabled && !customerFormGroup.valid changes value). This will be again handled in your parent component.

Last thing, in your child component, use async pipe to work with the value of that observable:

<button mat-button 
        (click)="onClickPrimaryActionEvent($event)" 
        [disabled]="primaryActionDisabled | async">{{ primaryActionText }}</button>

Upvotes: 1

Related Questions