如何将 ngModel 与表单内的自定义控件一起使用? [英] How to use ngModel with a custom control inside a form?
问题描述
我创建了一个用于处理选择框的组件,现在当我在提交表单后将其放入表单标签时,选择的结果不会显示在控制台中.
我的代码有什么问题?我该如何解决这个问题?
- testOption:是我传递的对象数组,使用
@Input
抛出选择框.
这里是选择框组件:
import { Component, OnInit, Input } from '@angular/core';@成分({选择器:'输入选择',模板:`<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></选择>
`})导出类 InputSelectComponent 实现 OnInit {@Input() 标签:字符串;@Input() 名称:字符串;@Input() 选项;//测试选项 = [//{value:'test',name:'test2'},//{value:'test',name:'test2'}//];构造函数(){}ngOnInit() {控制台日志(this.options);}}
在 html 中的使用:
表单 html:
控制台日志:(没有选择框值)
Object {name: "test", building-type: "tset" }
我想我现在知道你的问题了.
您想在自定义组件上实现 ControlValueAccessor
以在带有 ngModel
的表单内使用它!?
您的组件应如下所示:
@Component({选择器:'ng2-输入-选择',模板:`<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></选择>
`,供应商: [{/* idk 为什么或这会做什么..但它有效!;) */提供:NG_VALUE_ACCESSOR,useExisting: forwardRef(() => SelectBoxComponent),多:真}]})导出类 SelectBoxComponent 实现 OnInit、ControlValueAccessor {@Input() 标签:字符串;@Input() 名称:字符串;@Input() 选项;@Input() 值:字符串 = '';//ControlValueAccessor 实现//====================================//如果在我们的组件中更改了值,则调用private _onChange = (_: any) =>{ };//如果输入被触摸"则调用 .. !私人_onTouched = () =>{ };//传入更改..公共写值(val:任何){this.value = val;}public registerOnChange(fn: (_: any) => void): void { this._onChange = fn;}public registerOnTouched(fn: () => void): void { this._onTouched = fn;}}
现场演示:https://plnkr.co/edit/imCJmCoJaeGQiUMcyBwz?p=preview
更新
在表单组件中使用变更检测:
<ng2-input-select ngModel (ngModelChange)="selectBoxChanged($event)" label="b2" name="select2" [options]="testObject"></ng2-input-select>
I created a component for handling select box, now when I put it in form tag after submitted form the result of the selection doesn't show up in console.
What's the problem with my code? how can I fix this?
- testOption: is array of object I passed throw the select box with
@Input
.
here is select box component:
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>
form html:
<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: (there is no select box value)
Object {name: "test", building-type: "tset" }
I guess I got your problem now.
You want to implement ControlValueAccessor
on your custom component to use it inside of a form with 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 your form-component:
<ng2-input-select ngModel (ngModelChange)="selectBoxChanged($event)" label="b2" name="select2" [options]="testObject"></ng2-input-select>
这篇关于如何将 ngModel 与表单内的自定义控件一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!