Невозможно использовать числовой ввод с переключателем - PullRequest
0 голосов
/ 10 марта 2020

Ниже показано, что строковое значение работает, однако, если мой ввод является числом, оно не работает. Любые идеи, кроме как сделать переменную строкой?

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"
    };
}

1 Ответ

3 голосов
/ 10 марта 2020

Вместо использования [(ngModel)] для двухсторонней привязки вы можете реализовать двустороннюю привязку самостоятельно, приведя параметры в соответствие и обрабатывая события изменения.

Каждый вход для типа числительного c будет выглядеть так:

<input type="radio" name="foo" value="1" kendoRadioButton
  [ngModel]="model.foo.toString()" 
  (ngModelChange)="onFooChanged($event)" />

Ваш обработчик событий в вашем компоненте будет выглядеть так:

onFooChanged(value) {
  this.model.foo = parseInt(value);
}

Не зная, что происходит за кулисами с [(ngModel)], я предполагаю, что выполняет строгую проверку на равенство для логических типов, таких как переключатели.

DEMO: https://stackblitz.com/edit/angular-w3xwmx

Создание многоразового ввода

Создание события Обработчик каждого свойства быстро станет утомительным, если у вас есть несколько из них. В качестве альтернативы вы можете создать свой собственный компонент, который включает эту функцию.

number-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() : '';
  }
}

number-radio-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>

Вам потребуется передать дополнительные свойства, если вы хотите настроить входные данные по-другому, но, по крайней мере, это позволит вам связываться с вашей моделью напрямую. .

...