ng如果不更新Angular Reactive Forms中的视图



我有一个反应式表单,我从JSON中获取数据。它有单选按钮。在那里,如果用户点击"为他人",我想显示额外的字段(它已经在渲染)。如果用户单击"我",我想隐藏那个额外的字段。我在这里试过ngIf。但我的观点并没有更新。我还尝试了ngzone和settimeout选项。但什么都不管用。这是一个堆叠式示例

https://stackblitz.com/edit/github-ubotkt

有人能帮我处理这个吗

更新

作为您问题的解决方案,您可以执行以下操作:

  1. app-form-controlapp-form-main取出额外字段
  2. 使用app-form-control中的EventEmitterapp-form-controlapp-form-main之间进行通信
  3. EventEmitter将在无线电的(change)上被调用。它将发出当前检查的无线电的值/key/id
  4. 读取app-form-main中的值/key/id,并在此基础上显示/隐藏相应的额外字段

我已经在stackblitz上创建了您的示例代码。

原始答案(和实际问题)

你使用的方法很奇怪。

这就是你的代码中发生的事情:

  1. app-form-control创建了3次,每次用于:标题(请求的对象是谁?)、单选按钮(Me
  2. 现在,extendedFields的条件输出与每个app-form-control相关
  3. 所以,当你点击Me电台时,你看到的控制台来自Meapp-form-controlFor someone else也是如此
  4. 现在,当您单击For someone else时,条件标志showExtraField会发生变化,但它只对For someone elseapp-form-control发生变化
  5. 现在,当您单击Me时,条件标志shoeExtraField会更改,但它只会更改Meapp-form-controlFor someone elseapp-form-control的条件标志showExtraField保持原样
  6. 因此,由于条件标志不会更改,所以它不会隐藏额外的字段

我建议您更改创建表单控件的方法。否则,您将很难跟踪错误/问题。

Coderaizer,你需要知道你想要得到什么。看到你的代码,我想你想得到一些像

{answer:...,answerExt:...}

嗯,你的代码中有一些错误。(有些是概念错误)

表单中的ngOnInit主组件必须考虑数据何时具有密钥以及该密钥是否重复。如果你想获得上述数据

ngOnInit() {
const formContent: any = {};
this.dataList.forEach(data => {
//we check if the formContent has or not the property data.key
if (data.key && !formContent[data.key])
{
formContent[data.key] = new FormControl(data.value);
}
//we check if the formContent has or not the property data.key+"Ext"
if (data.extendedFields && !formContent[data.key+'Ext'])
formContent[data.key+'Ext'] = new FormControl(data.extendedFields.value);
});
this.quizForm = new FormGroup(formContent);
}

由于我们可以有两个控件(answer和answerExt),在您的表单控件组件中,在ngOnInit 中

ngOnInit() {
this.control = this.parentForm.get(this.data.key);
this.controlExt = this.parentForm.get(this.data.key+"Ext");
}

那么,您的form-control-component.html可以像一样

<h3>{{data.title}}</h3>
<label *ngIf="data.controlType == 'text'" [attr.for]="data.key">{{data.label}}</label>
<input *ngIf="data.controlType == 'text'" [type]="data.type">
<div *ngIf="data.controlType == 'radio'">
<ng-container *ngFor="let opt of data.options">
<label>
<!--see that we use formControl-->
<input style="margin-left: 5px;" [formControl]="control" type="radio"
<!--I use "data.id"-->
[name]="data.key" [value]="data.id"
[id]="data.quizId"> {{opt.key}}
</label>
</ng-container>
</div>
<!--the "if" is simple data.id=control.value-->
<div *ngIf="data.extendedFields && data.id==control.value">
<ng-container>
<label [attr.for]="data.key">{{data.extendedFields.text}}</label>
<!--see that we use formControl-->
<input *ngIf="data?.extendedFields.type == 'text'" [formControl]="controlExt">
</ng-container>
</div>

你可以在stackblitz 中看到工作

注意:有很多不必要的代码,并且数据列表的"地图"不清楚,尽量简单。因此,如果你选择了一个没有扩展字段的选项,你将具有值

您设置了错误的布尔值,这对我来说是true,对其他人来说是false

if(evt.target.value == "Me"){
this.showExtraField = false; //change this
}else if(evt.target.value == "For someone else") {
this.showExtraField =true; //change this
}

请确保*ngIf的绑定值应该是布尔值,在js中的某个时候,它被转换为字符串,那么*ngIf将无法按预期工作。

我的建议是使用操作员的类型再次交叉检查

只需将其嵌套到选项中即可解决问题。

<div [formGroup]="parentForm">
<h3>{{data.title}}</h3>
<label *ngIf="data.controlType == 'text'" [attr.for]="data.key">{{data.label}}</label>
<input *ngIf="data.controlType == 'text'" [type]="data.type">
<!--Single Radio button view-->
<div *ngIf="data.controlType == 'radio'">
<ng-container *ngFor="let opt of data.options">
<label>
<input style="margin-left: 5px;" #radio (change)="handleChange($event)" type="radio" [name]="data.key" [value]="data.options['0'].value"
[id]="data.quizId"> {{opt.key}}
</label>
<!--Extended field view-->
<div *ngIf="data.extendedFields && data.extendedFields.type">
<div *ngIf="data.extendedFields.type == 'text' && radio.checked">
<ng-container>
<label [attr.for]="data.key">{{data.extendedFields.text}}</label>
<input *ngIf="data?.extendedFields.type == 'text'" [formControlName]="data.key">
</ng-container>
</div>
</div>
</ng-container>
</div>

相关内容

最新更新