反应形式不绑定值

时间:2021-05-07 12:37:49

标签: angular typescript

我正在用 net 5 和 angular 11 开发 API 应用程序。我有可重用的组件,可用于响应式表单,但无法绑定值。我有一个表 IStTransaction,它有一个来自表 Stock 的外键 stockId。我想购买特定的库存,一切都以模板形式完美运行。但是当我尝试使用反应形式时,我能够进行交易,但是我的两个相关属性,价格和数量,显示值为 0。我很确定问题不在我的可重用组件中,因为我从一个关于 Udemy 的教程(谢谢,Neil:))并且一切正常,但我也会把它放在这里。这是我的代码的一部分,如果我应该放一些更多的代码,请告诉我。提前致谢:)

IStTransaction - 我只使用价格和数量,服务器处理其他属性

export class IStTransaction {
stockId: number = 0;
price: number = 0;
quantity: number = 0;
purchase: boolean = true;
resolved: number = 0;

可重用组件text-input.component.ts

@Component({
selector: 'app-text-input',
templateUrl: './text-input.component.html',
styleUrls: ['./text-input.component.scss']
})
export class TextInputComponent implements OnInit, ControlValueAccessor {
@ViewChild('input', {static: true}) input: ElementRef;
@Input() type = 'text';
@Input() label: string;

constructor(@Self() public controlDir: NgControl) {
this.controlDir.valueAccessor = this;
}

ngOnInit(): void {
const control = this.controlDir.control;
const validators = control.validator ? [control.validator] : [];
const asyncValidators = control.asyncValidator ? [control.asyncValidator] : [];

control.setValidators(validators);
control.setAsyncValidators(asyncValidators);
control.updateValueAndValidity();
}

onChange(event) {
}

onTouched() {
}

writeValue(obj: any): void {
this.input.nativeElement.value = obj || '';
}

registerOnChange(fn: any): void {
this.onChange = fn;
}

registerOnTouched(fn: any): void {
this.onTouched = fn;
}

text-input.component.html

<div class="form-label-group">
<input 
    [ngClass]="(controlDir && controlDir.control && controlDir.control.touched) ? 
    !controlDir.control.valid ? 'is-invalid' : 'is-valid' : null"
    [type]="type"
    (input)="onChange($event.target.value)"
    (blur)="onTouched()"
    id="{{label}}" 
    #input
    class="form-control" 
    placeholder="{{label}}"
  >

  <label for="{{label}}">{{label}}</label>

 <div class="invalid-feedback" *ngIf="(controlDir && controlDir.control 
 && !controlDir.control.valid && controlDir.control.touched)">
 <span *ngIf="controlDir.control.errors?.required">{{label}} is required</span>
 <span *ngIf="controlDir.control.errors?.pattern">Invalid email address</span>

 </div>

 <div class="invalid-feedback d-block" *ngIf="(controlDir && controlDir.control &&
 !controlDir.control.valid && controlDir.control.dirty)">
    <span *ngIf="controlDir.control.errors?.emailExists">Email address is in use</span>
 </div>
 </div>

add-stock-reactive-form.component.ts - 只是相关的代码

@Component({
selector: 'app-add-stock-reactive-form',
templateUrl: './add-stock-reactive-form.component.html',
styleUrls: ['./add-stock-reactive-form.component.scss']
})
export class AddStockReactiveFormComponent implements OnInit {
list: FormGroup;
stock: IStock;

ngOnInit(): void {
this.loadStock();
this.createForm();
}

 createForm() {
 this.list= new FormGroup({
 price: new FormControl('', [Validators.required]),
 quantity: new FormControl('', Validators.required)
 });
 }

onSubmit() {
this.service.formData.stockId = this.stock.id;
this.router.navigateByUrl('myportfolio');
this.service.buyStock1(this.loginForm.value).subscribe(() => {
this.resetForm(this.loginForm);
},
error => {
console.log(error);
});
}

add-stock-reactive-form.component.html

<div class="d-flex justify-content-center mt-3 mb-3">
    <div class="col-5">
    <div class="form-group">
        <input class="form-control form-control-lg" placeholder="{{stock?.symbol}}">
    </div>
    <form [formGroup]="list" (ngSubmit)="onSubmit()">
        <app-text-input formControlName="price" [label]="'Price'"></app-text-input>
        <app-text-input formControlName="quantity" [label]="'Quantity'"></app-text-input>
       
        <button [disabled]="list.invalid" class="btn btn-lg btn-primary btn-block" 
  type="submit">Submit</button>
      </form>
    </div>
  </div>

1 个答案:

答案 0 :(得分:0)

NG_VALUE_ACCESSOR 提供程序添加到您的自定义表单控件组件

@Component({
selector: 'app-text-input',
templateUrl: './text-input.component.html',
styleUrls: ['./text-input.component.scss'],
providers: [
  {
    provide: NG_VALUE_ACCESSOR,    // <-- Add to your custom form control component
    multi:true,
    useExisting: TextInputComponent
  }
]
})
export class TextInputComponent implements OnInit, ControlValueAccessor {

更新 尝试将您的自定义表单控件拉到 stackblitz 并修复了 text-input.component.html 中的编译错误

(input)="onChange($event.target.value)"(input)="onChange($event.target['value'])" 并且似乎工作正常。

Stackblitz link