How to use ngModel with a custom control inside a form?

I created a component for processing the selection window, now when I put it in the form tag after the submitted form, the selection result is not displayed in the console.

What is the problem with my code? how can i fix this?

  • testOption: an array of objects that I passed, selected a select box using @Input .

Here is the component of the selection window:

 import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'input-select', template:` <div class="field-select"> <span><icon name="select-arrow" size="10"></icon></span> <select name="{{name}}" class="field"> <option value="0" disabled selected>{{label}}</option> <option *ngFor="let option of options" [ngValue]="option.value">{{option.name}}</option> </select> </div> ` }) export class InputSelectComponent implements OnInit { @Input() label: string; @Input() name: string; @Input() options; // testOptions = [ // {value:'test',name:'test2'}, // {value:'test',name:'test2'} // ]; constructor() { } ngOnInit() { console.log(this.options); } } 

Usage in html:

 <input-select label="test" name="select2" [options]="testOption"></input-select> 

html form:

 <form role="form" class="form" #f="ngForm" (ngSubmit)="onSubmit(f)"> <input class="field" name="name" ngModel type="text" placeholder="n1"> <input-select label="b2" name="select2" [options]="testObject"></input-select> <input class="field" name="building-type" type="text" ngModel placeholder="b3"> </form> 

console log: (no selection window value)

 Object {name: "test", building-type: "tset" } 
+5
source share
3 answers

I guess I have your problem now.

Do you want to implement a ControlValueAccessor in your custom component to use it inside a form using ngModel !?

Your component should look like this:

 @Component({ selector: 'ng2-input-select', template: ` <div class="field-select"> <select name="{{ name }}" class="field" [(ngModel)]="value" (ngModelChange)="_onChange($event)"> <option value="" disabled selected>{{ label }}</option> <option *ngFor="let option of options" [value]="option.value">{{ option.name }}</option> </select> </div> `, providers: [ { /* idk why or what this will do exactly.. but it works! ;) */ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SelectBoxComponent), multi: true } ] }) export class SelectBoxComponent implements OnInit, ControlValueAccessor { @Input() label: string; @Input() name: string; @Input() options; @Input() value: string = ''; // ControlValueAccessor implementation // ==================================== // call if value was changed inside our component private _onChange = (_: any) => { }; // call if input was "touched" .. ! private _onTouched = () => { }; // incoming change.. public writeValue(val: any) { this.value = val; } public registerOnChange(fn: (_: any) => void): void { this._onChange = fn; } public registerOnTouched(fn: () => void): void { this._onTouched = fn; } } 

live-demo: https://plnkr.co/edit/imCJmCoJaeGQiUMcyBwz?p=preview

UPDATE

Using change detection in a form component:

 <ng2-input-select ngModel (ngModelChange)="selectBoxChanged($event)" label="b2" name="select2" [options]="testObject"></ng2-input-select> 
+6
source

try [value]="option.value" , by the way, you can show your console too.

0
source

You must bind ngModel as one of the attributes in your selector. Then print the ngModel value in the console.

0
source

Source: https://habr.com/ru/post/1263568/


All Articles