无法使用单选按钮输入数字
Unable to use number input with radio button
下面显示字符串值有效,但如果我输入的是数字,则无效。除了将变量变成字符串之外还有什么想法吗?
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<p>Model: {{model | json}}</p>
NOT WORKING<br/>
<input type="radio" name="foo" value="1" [(ngModel)]="model.foo" kendoRadioButton />
<input type="radio" name="foo" value="2" [(ngModel)]="model.foo" kendoRadioButton />
<input type="radio" name="foo" value="3" [(ngModel)]="model.foo" kendoRadioButton />
<br/>
WORKING<br/>
<input type="radio" name="bar" value="1" [(ngModel)]="model.bar" kendoRadioButton />
<input type="radio" name="bar" value="2" [(ngModel)]="model.bar" kendoRadioButton />
<input type="radio" name="bar" value="3" [(ngModel)]="model.bar" kendoRadioButton />
`
})
export class AppComponent {
public model = {
foo: 3,
bar: "2"
};
}
不是使用 [(ngModel)]
进行双向绑定,您可以通过字符串化设置和处理更改事件来自己实现双向绑定。
数字类型的每个输入如下所示:
<input type="radio" name="foo" value="1" kendoRadioButton
[ngModel]="model.foo.toString()"
(ngModelChange)="onFooChanged($event)" />
您的组件中的事件处理程序如下所示:
onFooChanged(value) {
this.model.foo = parseInt(value);
}
不知道 [(ngModel)]
的幕后发生了什么,我假设它正在对单选按钮等布尔类型进行严格的相等性检查。
演示:https://stackblitz.com/edit/angular-w3xwmx
创建可重复使用的输入
如果您有多个这样的事件处理程序,那么根据 属性 创建一个事件处理程序很快就会变得乏味。或者,您可以创建自己的组件来包装此功能。
数-radio.input.component.ts
import { Component, Input, forwardRef, ChangeDetectorRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
@Component({
selector: 'number-radio-input',
templateUrl: './number-radio-input.component.html',
providers: [
{ provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NumberRadioInputComponent),
multi: true }
]
})
export class NumberRadioInputComponent implements ControlValueAccessor {
@Input() name: string;
@Input() value: string;
model: string;
private _value: number;
private onChangeCallback: (value: number) => void = () => { };
onModelChange(): void {
this._value = parseInt(this.model, 10);
this.onChangeCallback(this._value);
}
registerOnChange(fn: (value: number) => void): void {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any): void {}
writeValue(val: number): void {
this._value = val;
this.model = val ? val.toString() : '';
}
}
数字广播-input.component.html
<input type="radio" [name]="name"
[value]="value"
[(ngModel)]="model" (ngModelChange)="onModelChange()" />
component.html
<number-radio-input [(ngModel)]="model.foo" value="1" name="foo">
</number-radio-input>
如果您想以不同方式配置输入,则需要传入其他属性,但至少这将允许您直接绑定到您的模型。
只需使用
[value]="1"
对“值”的单向绑定属性。
如此处所述:
下面显示字符串值有效,但如果我输入的是数字,则无效。除了将变量变成字符串之外还有什么想法吗?
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<p>Model: {{model | json}}</p>
NOT WORKING<br/>
<input type="radio" name="foo" value="1" [(ngModel)]="model.foo" kendoRadioButton />
<input type="radio" name="foo" value="2" [(ngModel)]="model.foo" kendoRadioButton />
<input type="radio" name="foo" value="3" [(ngModel)]="model.foo" kendoRadioButton />
<br/>
WORKING<br/>
<input type="radio" name="bar" value="1" [(ngModel)]="model.bar" kendoRadioButton />
<input type="radio" name="bar" value="2" [(ngModel)]="model.bar" kendoRadioButton />
<input type="radio" name="bar" value="3" [(ngModel)]="model.bar" kendoRadioButton />
`
})
export class AppComponent {
public model = {
foo: 3,
bar: "2"
};
}
不是使用 [(ngModel)]
进行双向绑定,您可以通过字符串化设置和处理更改事件来自己实现双向绑定。
数字类型的每个输入如下所示:
<input type="radio" name="foo" value="1" kendoRadioButton
[ngModel]="model.foo.toString()"
(ngModelChange)="onFooChanged($event)" />
您的组件中的事件处理程序如下所示:
onFooChanged(value) {
this.model.foo = parseInt(value);
}
不知道 [(ngModel)]
的幕后发生了什么,我假设它正在对单选按钮等布尔类型进行严格的相等性检查。
演示:https://stackblitz.com/edit/angular-w3xwmx
创建可重复使用的输入
如果您有多个这样的事件处理程序,那么根据 属性 创建一个事件处理程序很快就会变得乏味。或者,您可以创建自己的组件来包装此功能。
数-radio.input.component.ts
import { Component, Input, forwardRef, ChangeDetectorRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
@Component({
selector: 'number-radio-input',
templateUrl: './number-radio-input.component.html',
providers: [
{ provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NumberRadioInputComponent),
multi: true }
]
})
export class NumberRadioInputComponent implements ControlValueAccessor {
@Input() name: string;
@Input() value: string;
model: string;
private _value: number;
private onChangeCallback: (value: number) => void = () => { };
onModelChange(): void {
this._value = parseInt(this.model, 10);
this.onChangeCallback(this._value);
}
registerOnChange(fn: (value: number) => void): void {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any): void {}
writeValue(val: number): void {
this._value = val;
this.model = val ? val.toString() : '';
}
}
数字广播-input.component.html
<input type="radio" [name]="name"
[value]="value"
[(ngModel)]="model" (ngModelChange)="onModelChange()" />
component.html
<number-radio-input [(ngModel)]="model.foo" value="1" name="foo">
</number-radio-input>
如果您想以不同方式配置输入,则需要传入其他属性,但至少这将允许您直接绑定到您的模型。
只需使用
[value]="1"
对“值”的单向绑定属性。
如此处所述: