我正在尝试为 <select>
创建自定义表单控件组件元素(我意识到这不是创建自定义表单控件的最具创新性的用途,但这只是为了测试目的)。我正在关注教程 @ http://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html .
我的目标是禁用提交按钮,直到从 <select-box>
中选择了一个值。组件,但我认为我没有正确连接自定义表单控件,因为当我选择不同的值时值不会改变,验证也不起作用(验证 = 只是自定义组件上的 required
HTML 属性) .
请参阅下文,了解我目前所掌握的内容。或者,可以在 http://plnkr.co/edit/TAxDyb8sHg158dXmyfwr?p=preview 找到一个 plunker。 .
谢谢!
主要成分
import {Component, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {SelectBoxComponent} from "./select-box.component";
import {FormsModule} from "@angular/forms";
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<form #form="ngForm" (ngSubmit)="log(form.value)">
<select-box name="someValue" [ngModel]="someValue" required></select-box>
<br>
<button type="submit" [disabled]="!form.valid">Submit</button>
</form>
<br>
{{ form.value | json }}
</div>
`,
})
export class App {
name:string;
someValue: any = 1;
log(str) {
console.log(str);
}
}
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ App, SelectBoxComponent ],
bootstrap: [ App ]
})
export class AppModule {}
选择框组件
import { Component, forwardRef, Input } from "@angular/core";
import { SelectControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
@Component({
selector: "select-box",
template: `
<select onchange="onChanged(event.target.value)" [ngModel]="ngModel">
<option disabled selected value></option>
<option value="1">1</option>
<option value="2">2</option>
</select>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SelectBoxComponent),
multi: true,
}
],
})
export class SelectBoxComponent implements SelectControlValueAccessor {
@Input() ngModel: any;
onChanged(value) {
this.ngModel = value;
this.propagateChange(value);
}
writeValue(value: any) {
if (value) this.value = value;
}
propagateChange = (_: any) => {};
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched() {}
}
最佳答案
此处为您的组件修复:http://plnkr.co/edit/69SGnjYGBWhC4tEezc1G?p=preview
<select [(ngModel)]="selectValue">
<option disabled selected value></option>
<option value="1">1</option>
<option value="2">2</option>
</select>
在 .ts
中:
export class SelectBoxComponent implements ControlValueAccessor {
private _selectValue: any = '';
private _onTouchedCallback: () => {};
private _onChangeCallback: (_:any) => {};
hasValue: boolean;
get selectValue(): any {
return this._selectValue;
}
set selectValue(value: any) {
if (value !== this._selectValue) {
this._selectValue = value;
this._onChangeCallback(value);
}
this.hasValue = (value != null && value.length > 0)
this._onTouchedCallback();
}
//From ControlValueAccessor interface
writeValue(value: any) {
this._selectValue = value;
}
//From ControlValueAccessor interface
registerOnChange(fn: any) {
this._onChangeCallback = fn;
}
//From ControlValueAccessor interface
registerOnTouched(fn: any) {
this._onTouchedCallback = fn;
}
}
在您的选择组件中,有一些错误。
- 您没有正确绑定(bind)模型。添加 getter/setter,以便您可以跟踪更改并使用
this._onChangeCallback
和this._onTouchedCallback();
通知它
- 您需要注册
registerOnTouched
事件并触发它。这样,您的模型可以变得脏
,并且您的表单可以检测更改是否有效。
关于javascript - 在 Angular 2 中创建自定义表单控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40009149/