0

This is not a question on how to do Angular bindings. It's not about ngModel etc.

It's about a feature that I've just been educated on, seemingly working and quite nicely.

I've never heard of it and I can't confirm it in any documentation I've looked into.

I asked a question and got a few answers, one of which was spot-on and easy to implement.

Basically, it's about the two-way binding that works automagically without implementing ControlValueAccessor nor manually mapping values to the model in the view component from the custom control component. I only had to put in an @Output suffixed by Change in the custom component and banana-box in the view component and tada! it works.

custom.component.ts

@Input() value: string;
@Output() valueChange: EventEmitter<string>;

view.component.html

<app-custom [(value)]="model.someField"></app-custom>
<app-custom [(value)]="model.anotherField"></app-custom>

Where is this behavior documented? Is it some special case of ngModel that I don't comprehend or just a nice feature not widely known?

I'm afraid that it's just a fluke and not something that's going to be supported in the future.

yivi
  • 42,438
  • 18
  • 116
  • 138
DonkeyBanana
  • 3,266
  • 4
  • 26
  • 65

2 Answers2

3

This behaviour is proper and documented in angular docs. it is not some "un official hack"

According to docs:

Angular offers a special two-way data binding syntax for this purpose, [()]. The [()] syntax combines the brackets of property binding, [], with the parentheses of event binding, (). The [()] syntax is easy to demonstrate when the element has a settable property called x and a corresponding event named xChange. Here's a SizerComponent that fits this pattern. It has a size value property and a companion sizeChange event:

The official docs even gives an example of it

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-sizer',
  templateUrl: './sizer.component.html',
  styleUrls: ['./sizer.component.css']
})
export class SizerComponent {


  @Input()  size: number | string;
  @Output() sizeChange = new EventEmitter<number>();

  dec() { this.resize(-1); }
  inc() { this.resize(+1); }

  resize(delta: number) {
    this.size = Math.min(40, Math.max(8, +this.size + delta));
    this.sizeChange.emit(this.size);
  }

}

so rest assured it is not something which might be removed without any notice.

BUT

just an FYI if you plan on using [ngModel] and (ngModelChange)
alt255
  • 3,396
  • 2
  • 14
  • 20
  • Regarding your butt - it says that *has been deprecated for a few reasons* about `ngModel`. Am I to understand that the concept isn't used in Angular 7 at all? That's a first time I hear about this. I prefer the *x* and *xChange* pattern immensely better. – DonkeyBanana Aug 19 '19 at 15:15
  • you can use x and xChange pattern for custom components in all angular version . Starting with version 7 you can not ngModel and ngModelChange i.e template driven form. the reasons are given in the link above – alt255 Aug 19 '19 at 18:11
2

Two-way bindings (or bananabox) are quite common and a nifty little thing for those dumb/smart component patterns.

https://angular.io/guide/template-syntax#two-way-binding-

Don't worry, it's not going away

yivi
  • 42,438
  • 18
  • 116
  • 138
cnps
  • 151
  • 10
  • Please read the full content of the question. It's not nearly as broad as the banana notations for two way binding. It's very specific related to the suffix *xxxChange* which I wasn't even aware of. – DonkeyBanana Aug 20 '19 at 15:35
  • @DonkeyBanana okay, then i'm not really sure of what you are asking about, if it's not documumentation on [()]. [()] is essentially the same as . Only with the "Change" suffix, can angular know they are the same value. And the event change value, should be the property binding's source value. You can even bind the event binding to a method and do something with the event there. – cnps Aug 22 '19 at 08:58
  • Not sure how to elaborate it further. The question isn't "*what's a banana box and how does it work*". It's "*where is the effect suffix **Change** documented*". – DonkeyBanana Aug 25 '19 at 15:24