Search code examples
angular2-way-object-databinding

Angular: 2 way data binding for a custom input in a child component


How to make 2-way data binding for a custom input in child component in Angular 8?

I used banana-in-a-box [(...)] syntax but it doesn't make changes in child component visible in the parent component.

In the result, it should work with the banana-in-a-box syntax.

parent.component.ts

...
public childVisibility: boolean = true;
...

parent.component.html

childVisibility : {{childVisibility}}

<app-child-component [(visible)]="childVisibility">
</app-child-component>

child.component.ts

@Component({
  selector: 'app-child-component',
  templateUrl: './app-child.component.html',
  styleUrls: ['./global-search-results.component.scss']
})
export class ChildComponent {
  @Input() visible: boolean;

  constructor() {}

  public changeVisible() { 
    this.visible = false;
  }
}

child.component.html

<button (click)="changeVisible()">
  Change Visible
</button>

Solution

  • child.component.ts

    @Input()  visible: boolean;
    @Output() visibleChange = new EventEmitter<boolean>();
    
    public changeVisible() { 
       this.visible = false;
       this.visibleChange.emit(this.visible);
    }
    

    parent.component.html

    <app-child-component [(visible)]="childVisibility">
    </app-child-component>
    

    The cause here is the suffix 'Change' in the event's name visibleChange. If the property binding name is 'x', the event binding name should be exactly 'xChange'. Only then angular recognizes banana-in-a-box [()] syntax.

    Detailed example: http://embed.plnkr.co/Jcu0iNkaUeRF7KEF7wA4/