ng如果未更新Angular反应性表单中的视图

时间:2019-01-31 05:24:12

标签: angular angular-forms reactive-forms

我有一个响应式表单,我正在从JSON获取数据。它具有单选按钮。如果用户单击“对于其他人”,我想在其中显示额外的字段(已经渲染)。如果用户单击“我”,我想隐藏该多余的字段。我在这里尝试了ngIf。但是我的观点没有更新。我也尝试了ngzone和settimeout选项。但是没有任何效果。这是一个令人难以置信的例子

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

有人可以帮我吗

5 个答案:

答案 0 :(得分:1)

更新

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

  1. app-form-controlapp-form-main提取额外的字段
  2. 使用EventEmitter中的app-form-controlapp-form-controlapp-form-main之间进行通信。
  3. EventEmitter会在(change)的收音机中被调用。这将发出当前检查的收音机的值/密钥/ ID。
  4. app-form-main中读取该值/键/ id,并根据该显示/隐藏相应的额外字段。

我在stackblitz上从您这里创建了示例代码。

原始答案(和实际问题)

您使用的方法很奇怪。

这就是您的代码所发生的事情:

  1. app-form-control被创建3次,每次用于:标题(此请求是谁?),单选按钮( Me ),单选按钮(用于其他人
  2. 现在,extendedFields的条件输出与每个app-form-control相关。
  3. 因此,当您单击Me广播时,您看到的控制台来自Me的{​​{1}},而app-form-control也会出现同样的情况。
  4. li>
  5. 现在,当您单击For someone else时,条件标志For someone else会发生变化,但仅对于showExtraField的{​​{1}}会发生变化。
  6. 现在,当您单击For someone else时,条件标志app-form-control会发生变化,但仅对于Me的{​​{1}}会发生变化。 shoeExtraField的{​​{1}}的条件标志Me保持不变。
  7. 因此,由于条件标志不变,因此不会隐藏额外的字段。

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

答案 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>