NGFOR具有WebAPI的动态数据

发布于 2025-02-09 13:54:11 字数 2460 浏览 4 评论 0原文

我有一个从WebAPI加载的问题列表。根据QuartionType,答案是无线电选项/文本。现在,我想验证我的答案(必需/自定义验证器)。在WebAPI返回问题列表之后,我将FormControl添加到FormGroup中。

错误 - NG0100:ExpressionChangedAfterithasbeenCheckedError:表达在检查后发生了变化。上一个值:'[对象对象]'。当前值:“未定义” ..

如果 *ngif =“ Questionform”从HTML中删除,则 错误 - FormGroup期望一个FormGroup实例。请传递一个。

据我的理解,创建了formGroup实例,并且在角生命周期中的某个地方再次重新加载了它。

.html

<form *ngIf="questionForm" [formGroup]="questionForm">
 <ng-container *ngFor="let item of Questions;let i = index;">
        <mat-label >{{item.question}}</mat-label>
        <div [ngSwitch]="item.questionType">
            <div *ngSwitchCase="'bool'">
               <mat-radio-group class="radio__button" aria- 
               label="Select an option">
               <mat-radio-button id="YesAnswer_{{item.id}}" 
                #Answer_{{item.id}}
                name="Answer_{{item.id}}" value="1" 
                formControlName="Answer_{{item.id}}">Yes</mat-radio- 
                button>
               <mat-radio-button id="NoAnswer_{{item.id}}" 
                 #Answer_{{item.id}}
                 name="Answer_{{item.id}}" value="0" 
                 formControlName="Answer_{{item.id}}">No</mat-radio- 
                button>
               </mat-radio-group>
             </div>
             <div *ngSwitchCase="'string'">
                  <mat-form-field appearance="outline">
                   <input matInput type="text" 
                    id="Answer_{{item.id}}" #Answer_{{item.id}}
                     formControlName="Answer_{{item.id}}" 
                     name="Answer_{{item.id}}">
                   </mat-form-field>
              </div>
      </div>
    </ng-container>
</form>

.ts file ngoninit()方法。 这个问题保留了WebAPI的问题列表,我确保以下代码仅在加载问题后运行。下面该声明显示了FormGroup中的控件列表。

 ngOnInit():void{
    this.service.GetQuestion().subscribe({
          error: (err) => { console.log(err); },
          next: (data) => {
            if (data) {
              this.Questions = data as Questions[];
        this.questionForm = new FormGroup ({});
        this.Questions.forEach(quest=>{
              this.questionForm.addControl('Answer_'+String(quest.id),new FormControl( '', 
              [Validators.required]));
              });
        }

I have a list of questions loaded from WebAPI. Based on the questionType, the answer is either radio options/text. Now I want to validate my answers(required/custom validator). I added formcontrol to formgroup dynamically after the webAPI returns the list of questions.

Error -
NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '[object Object]'. Current value: 'undefined'..

If *ngIf="questionForm" is removed from html, then
Error - formGroup expects a FormGroup instance. Please pass one in.

To my understanding, the formgroup instance is created and it gets reloaded as undefined again somewhere in the angular lifecycle.

.html

<form *ngIf="questionForm" [formGroup]="questionForm">
 <ng-container *ngFor="let item of Questions;let i = index;">
        <mat-label >{{item.question}}</mat-label>
        <div [ngSwitch]="item.questionType">
            <div *ngSwitchCase="'bool'">
               <mat-radio-group class="radio__button" aria- 
               label="Select an option">
               <mat-radio-button id="YesAnswer_{{item.id}}" 
                #Answer_{{item.id}}
                name="Answer_{{item.id}}" value="1" 
                formControlName="Answer_{{item.id}}">Yes</mat-radio- 
                button>
               <mat-radio-button id="NoAnswer_{{item.id}}" 
                 #Answer_{{item.id}}
                 name="Answer_{{item.id}}" value="0" 
                 formControlName="Answer_{{item.id}}">No</mat-radio- 
                button>
               </mat-radio-group>
             </div>
             <div *ngSwitchCase="'string'">
                  <mat-form-field appearance="outline">
                   <input matInput type="text" 
                    id="Answer_{{item.id}}" #Answer_{{item.id}}
                     formControlName="Answer_{{item.id}}" 
                     name="Answer_{{item.id}}">
                   </mat-form-field>
              </div>
      </div>
    </ng-container>
</form>

.ts file ngOnInit() method.
this.Questions holds the list of questions from WebAPI and I made sure that the below code runs only after the Questions are loaded.Adding a console.log(this.questionForm); below this statement shows the list of controls in the FormGroup.

 ngOnInit():void{
    this.service.GetQuestion().subscribe({
          error: (err) => { console.log(err); },
          next: (data) => {
            if (data) {
              this.Questions = data as Questions[];
        this.questionForm = new FormGroup ({});
        this.Questions.forEach(quest=>{
              this.questionForm.addControl('Answer_'+String(quest.id),new FormControl( '', 
              [Validators.required]));
              });
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦回旧景 2025-02-16 13:54:12

修复了问题...它不是创建动态表格组的问题,它是我声明FormGroup的地方...

我在此父组件中有一个子组件,并使用@viewchild Decorator作为子组件参考。当我声明自己的formgroup时,我将这两个语句置于我忽略的这两个语句之间,这引起了所有错误。

@ViewChild('myChild')
public myChildControl: MyChildComponent;

通过错误地将我的FormGroup声明放置在下面的formgroup声明下方,

@ViewChild('myChild')
questionForm: FormGroup =new FormGroup({});
public myChildControl: MyChildComponent;

将其移动到我的ChildComponent参考下,修复了错误。

感谢Eliseo的投入。

Fixed the issue...Its not the issue with creating dynamic form group, its where I declared the formgroup...

I had a child component in this parent component and used @ViewChild decorator for the child component reference. When I declared my formgroup, I placed inbetween these two statement, which I overlooked and that caused all the errors.

@ViewChild('myChild')
public myChildControl: MyChildComponent;

By mistakenly placed my formgroup declaration like below

@ViewChild('myChild')
questionForm: FormGroup =new FormGroup({});
public myChildControl: MyChildComponent;

Moving it below my childcomponent reference fixed the errors.

Thanks Eliseo for your input.

丢了幸福的猪 2025-02-16 13:54:11

尝试重命名接口的名称问题 to 问题

好吧,我想说您在使用MAT-RADIO-GROUP时,这就是您使用formControlname的地方。顺便说一句,我不太喜欢使用插值,使用绑定,并且您的标签定位错误。

这是我的.html

<form *ngIf="questionForm" [formGroup]="questionForm">
  <ng-container *ngFor="let item of Questions; let i = index">
    <div [ngSwitch]="item.questionType">
      <div *ngSwitchCase="'bool'">
        <mat-label>{{ item.question }}</mat-label>
        <div>
          <mat-radio-group
            class="radio__button"
            [formControlName]="'Answer_' + item.id"
            aria-label="Select an option"
          >
            <mat-radio-button value="1">Yes</mat-radio-button>
            <mat-radio-button value="0">No</mat-radio-button>
          </mat-radio-group>
        </div>
      </div>
      <div *ngSwitchCase="'string'">
        <mat-form-field appearance="outline">
          <mat-label>{{ item.question }}</mat-label>
          <input matInput type="text" [formControlName]="'Answer_' + item.id" />
        </mat-form-field>
      </div>
    </div>
  </ng-container>
</form>

和a stackblitz 顺便说一句,界面问题)

,当您使用formControls的formarray时,您只能在您需要的formControls中使用验证器,而不是在整个formarray-中 -

Try to rename the name of the Interface Questionsto Question

Well, I want to say your that when you use a mat-radio-group, it's this where you use formControlName. BTW I don't like so much the use of interpolation, use binding and you has wrong positioned the label.

This is my .html

<form *ngIf="questionForm" [formGroup]="questionForm">
  <ng-container *ngFor="let item of Questions; let i = index">
    <div [ngSwitch]="item.questionType">
      <div *ngSwitchCase="'bool'">
        <mat-label>{{ item.question }}</mat-label>
        <div>
          <mat-radio-group
            class="radio__button"
            [formControlName]="'Answer_' + item.id"
            aria-label="Select an option"
          >
            <mat-radio-button value="1">Yes</mat-radio-button>
            <mat-radio-button value="0">No</mat-radio-button>
          </mat-radio-group>
        </div>
      </div>
      <div *ngSwitchCase="'string'">
        <mat-form-field appearance="outline">
          <mat-label>{{ item.question }}</mat-label>
          <input matInput type="text" [formControlName]="'Answer_' + item.id" />
        </mat-form-field>
      </div>
    </div>
  </ng-container>
</form>

And a stackblitz that works (and is your code -well, I change the interface Questions by Question)

BTW, when you use a FormArray of FormControls you can use validator only in the FormControls you need -not in the whole FormArray-

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文