How to implement ngModel on custom elements?

Given a simple input element I can do this:

<input [(ngModel)]="name" /> {{ name }}

This doesn't work for my custom elements:

<my-selfmade-combobox [(ngModel)]="name" values="getValues()" required></my-selfmade-combobox>

How can I implement it?


Solution 1:

[(ngModel)]="item" is a shorthand for [ngModel]="item" (ngModelChange)="item = $event"

That means that if you want to add a 2-way bind property to your component, for example

<app-my-control [(myProp)]="value"></app-my-control>

All you need to do in your component is add

@Input()
myProp: string;

// Output prop name must be Input prop name + 'Change'
// Use in your component to write an updated value back out to the parent
@Output()
myPropChange = new EventEmitter<string>();

The @Input will handle the write ins and to write a new value back out to the parent, just call this.myPropChange.emit("Awesome") (You can put the emit in a setter for your property if you just want to make sure it is updated every time the value changes.)

You can read a more detailed explanation of how/why it works here.


If you want to use the name ngModel (because there are extra directives that bind to elements with ngModel), or this is for a FormControl element rather than a component (AKA, for use in an ngForm), then you will need to play with the ControlValueAccessor. A detailed explanation for making your own FormControl and why it works can be read here.

Solution 2:

If you really need [(ngModel)] (which supports ngForm, unlike [(myProp)] approach), I think this link will answer your question:

  • Angular 2 custom form input

We need to implement two things to achieve that:

  • A component that provides the logic of your form component. It doesn't need an input since that will be provided by ngModel itself
  • A custom ControlValueAccessor that will implement the bridge between this component and ngModel / ngControl

The previous link gives you a complete sample...