typescript 默认值不适用于ngModel,但适用于React式表单

cl25kdpy  于 2023-04-22  发布在  TypeScript
关注(0)|答案(1)|浏览(133)

我有一个单选按钮组组件,当我使用ngModel时,组件的值是null,尽管默认情况下它被设置为jkl。当我使用React形式时,值是FormControl的值,即def,它可以工作。
我创建了这个示例组件来测试值:

@Component({
  selector: 'example-radio-group-forms',
  standalone: true,
  imports: [CommonModule, RadioButtonModule, FormsModule, ReactiveFormsModule],
  template: `
    <form [formGroup]="exampleGroup">
      <radio-group formControlName="example" name="reactive-radio">
        <radio-button value="abc">ABC</radio-button>
        <radio-button value="def">DEF</radio-button>
      </radio-group>
      <p>Reactive Forms Result: {{ exampleGroup.get('example')?.value }}</p>
    </form>
    <radio-group [(ngModel)]="inputBinding" name="template-radio">
      <radio-button value="ghi">GHI</radio-button>
      <radio-button value="jkl">JKL</radio-button>
    </radio-group>
    <p>Template Driven Result: {{ inputBinding }}</p>
  `,
})
export class RadioGroupFormsExample {
  // This one works
  exampleGroup = new FormGroup({
    example: new FormControl('def'),
  });

  // This one doesn't
  inputBinding = 'jkl';
}

然后,我有这两个组件模块,它们扩展了我的ValueAccessor组件。

@NgModule({
  declarations: [RadioButton, RadioGroup],
  imports: [CommonModule, FormsModule, ReactiveFormsModule, MatRadioModule],
  exports: [RadioButton, RadioGroup],
})
export class RadioButtonModule {}

@Component({
  selector: 'radio-group',
  template: `
    <mat-radio-group
      #radioGroup
      [(ngModel)]="value"
    >
      <ng-content></ng-content>
    </mat-radio-group>
  `,
  styleUrls: ['./radio-group.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => RadioGroup),
      multi: true,
    },
  ],
})
export class RadioGroup<T = any> extends ValueAccessor<T> {
  ngAfterViewInit() {
    // ngModel = null
    // reactive form = 'def'
    console.debug(this.value);
  }
}

@Component({
  selector: 'radio-button',
  templateUrl: './radio-button.component.html',
  styleUrls: ['./radio-button.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => RadioButton),
      multi: true,
    },
  ],
})
export class RadioButton<T = any> extends ValueAccessor<T> {}

然后,我的ValueAccessor组件处理onChangeonTouchwriteValue

@Component({ template: '' })
export class ValueAccessor<T> implements ControlValueAccessor {
  @Input() disabled = false;
  @Input() required = false;
  @Input() name = '';
  protected _value?: T;
  get value(): T | undefined {
    return this._value;
  }
  @Input()
  set value(value: T | undefined) {
    this._value = value;
    this.onChange(value);
    if (this.onTouched) {
      this.onTouched();
    }
  }
  protected onChange = (_: T | undefined) => {};
  protected onTouched = () => {};
  registerOnChange(fn: () => T): void {
    this.onChange = fn;
  }
  registerOnTouched(fn: () => T): void {
    this.onTouched = fn;
  }
  writeValue(value: T): void {
    if (value !== undefined) {
      this.value = value;
    }
  }
}
kzipqqlq

kzipqqlq1#

尝试在settimeout中包含写入值“给予time”Angular绘制单选按钮

writeValue(value: T): void {
  setTimeout(()=>{
     if (value !== undefined) {
       this.value = value;
  }})
}

相关问题