我有一个响应式表单,我正在从JSON获取数据。它具有单选按钮。如果用户单击“对于其他人”,我想在其中显示额外的字段(已经渲染)。如果用户单击“我”,我想隐藏该多余的字段。我在这里尝试了ngIf。但是我的观点没有更新。我也尝试了ngzone和settimeout选项。但是没有任何效果。这是一个令人难以置信的例子
https://stackblitz.com/edit/github-ubotkt
有人可以帮我吗
答案 0 :(得分:1)
更新
作为解决问题的方法,您可以执行以下操作:
app-form-control
到app-form-main
提取额外的字段EventEmitter
中的app-form-control
在app-form-control
和app-form-main
之间进行通信。EventEmitter
会在(change)
的收音机中被调用。这将发出当前检查的收音机的值/密钥/ ID。app-form-main
中读取该值/键/ id,并根据该显示/隐藏相应的额外字段。我在stackblitz上从您这里创建了示例代码。
原始答案(和实际问题)
您使用的方法很奇怪。
这就是您的代码所发生的事情:
app-form-control
被创建3次,每次用于:标题(此请求是谁?),单选按钮( Me ),单选按钮(用于其他人)extendedFields
的条件输出与每个app-form-control
相关。Me
广播时,您看到的控制台来自Me
的{{1}},而app-form-control
也会出现同样的情况。For someone else
时,条件标志For someone else
会发生变化,但仅对于showExtraField
的{{1}}会发生变化。For someone else
时,条件标志app-form-control
会发生变化,但仅对于Me
的{{1}}会发生变化。 shoeExtraField
的{{1}}的条件标志Me
保持不变。我建议您更改创建表单控件的方法。否则,您将很难跟踪错误/问题。
答案 1 :(得分:1)
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);
}
在表单控件组件的ngOnInit中,我们可以有两个控件(answer和answerExt)
ngOnInit() {
this.control = this.parentForm.get(this.data.key);
this.controlExt = this.parentForm.get(this.data.key+"Ext");
}
然后,表单 - 控制 - 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
中查看工作注意:有很多不必要的代码,并且数据列表的“映射”不明确,请尝试对其进行简化。因此,如果您选择的选项没有延伸的字段,那么您要得到的值就是
答案 2 :(得分:0)
您设置的布尔值错误,对我来说是正确的,而对于其他人则是错误的
if(evt.target.value == "Me"){
this.showExtraField = false; //change this
}else if(evt.target.value == "For someone else") {
this.showExtraField =true; //change this
}
答案 3 :(得分:0)
请确保绑定到* ngIf的绑定值应为布尔值,在js中有时将其转换为字符串,然后* ngIf将无法按预期工作。
我的建议是使用typeof运算符再次进行交叉检查
答案 4 :(得分:-1)
只需将其嵌套到选项中即可解决问题。
<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>