动态表单控件在响应式表单中 – Angular

huangapple go评论89阅读模式
英文:

dynamic formcontrol in reactive forms - angular

问题

我在组件的 .ts 文件中有一个动态的 formControl,其中 addControl 的使用如下:

//...
this.reportList = this.data.reportList; 
for (let i = 0; i < this.reportList.length; i++) {
    const key = this.reportList[i].quesId;
    this.afterActionReportForm.addControl(key, new FormControl(this.reportList[i].boardAnswers));
}
...///

我的组件的 .html 文件代码如下:

<div class="row" *ngIf="reportList && reportList.length > 0" style="padding:10px;">
    <div *ngFor="let e of reportList; let i = index" class="col-sm-6" style="margin-top: 2em;">
        {{i+1}}. {{e.question}}
        <textarea style="width:100%" #{{e.quesId}} rows="8" cols="75" maxlength="500" formControlName="{{e.quesId}}"
        class="form-control"  pInputTextArea ></textarea>
        <span> {{e.boardAnswers.length}} of 500 characters</span>
    </div>
</div>

显示部分工作正常。但是 <span> 标签中的计数是实时计算的,根据输入的文本在界面中显示。

例如,初始时显示 "25 of 500 characters",随着继续输入,计数器应该逐渐增加。我在静态表单中实现了这一点,代码如下:

<div class="col-sm-10">
    <textarea style="width:80%" #message rows="8" cols="75" maxlength="500" 
    formControlName="message" class="form-control" pInputTextArea ></textarea>
    <span> {{message.value?.length || 0}} of 500 characters</span>
</div>

但是同样的概念在动态表单中不起作用。{{e.boardAnswers.length}} 只在页面加载时给出值,但是在文本区域中输入文本时并不会增加。如何在动态表单中处理这个问题?请提供建议。

英文:

I have a dynamic formControl where addControl is as follows in my component.ts file:

//...
this.reportList = this.data.reportList; 
for (let i = 0; i &lt; this.reportList.length; i++) {
	const key = this.reportList[i].quesId+&#39;&#39;;
	this.afterActionReportForm.addControl(key, new FormControl(this.reportList[i].boardAnswers));
}
...///

my component.html file code looks as follows:

&lt;div  class=&quot;row&quot; *ngIf=&quot;reportList &amp;&amp; reportList.length &gt; 0&quot; style=&quot;padding:10px;&quot;&gt;
	&lt;div *ngFor=&quot;let e of reportList; let i = index&quot; class=&quot;col-sm-6&quot; style=&quot;margin-top: 2em;&quot;&gt;
		{{i+1}}. {{e.question}}
		&lt;textarea style=&quot;width:100%&quot; #{{e.quesId}} rows=&quot;8&quot; cols=&quot;75&quot; maxlength=&quot;500&quot; formControlName=&quot;{{e.quesId}}&quot;
		class=&quot;form-control&quot;  pInputTextArea &gt;&lt;/textarea&gt;
		&lt;span&gt; {{e.boardAnswers.length}} of 500 characters&lt;/span&gt;
	&lt;/div&gt;
&lt;/div&gt;

The display part is working fine. But the span has a count which id calculated on the fly and shows up in the UI based on what the textArea is inputed.

like for example shows 25 of 500 characters and as you keep typing the counter has to increase. I was able to do that for my static form as follows:
This one works in static form:

&lt;div class=&quot;col-sm-10&quot;&gt;
	&lt;textarea style=&quot;width:80%&quot; #message rows=&quot;8&quot; cols=&quot;75&quot; maxlength=&quot;500&quot; 
	formControlName=&quot;message&quot; class=&quot;form-control&quot;  pInputTextArea &gt;&lt;/textarea&gt;
	&lt;span&gt; {{message.value?.length || 0}} of 500 characters&lt;/span&gt;
&lt;/div&gt;

But the same concept doesnt work for dynamic form.{{e.boardAnswers.length}} gives me value only when the page loads up, however when i type in the textArea it doesnt increment.
How do I handle the same with dynamic forms. Suggestions please?

答案1

得分: 1

以下是翻译好的内容:

工作脚本:

app.component.html
<form [formGroup]="afterActionReportForm">
  <div class="row" *ngIf="reportList && reportList.length > 0" style="padding:10px;">
    <div *ngFor="let e of reportList; let i = index" class="col-sm-6" style="margin-top: 2em;">
        {{i+1}}. {{e.question}}
        <textarea style="width:100%" #{{e.quesId}} rows="8" cols="75" maxlength="500" [formControlName]="e.quesId"
        class="form-control" pInputTextArea></textarea>
        <span> {{afterActionReportForm.get(e.quesId.toString()).value.length}} of 500 characters</span>
    </div>
  </div>
</form>
app.component.ts

ngOnInit() {
  this.afterActionReportForm = new FormGroup({});
  this.reportList = this.data.reportList;
  for (let i = 0; i < this.reportList.length; i++) {
      const key = this.reportList[i].quesId+'';
      this.afterActionReportForm.addControl(key, new FormControl(this.reportList[i].boardAnswers));
  }
}

更好的方法是为计算长度创建一个方法:

getStrLength(key: string | number): number {
    return this.afterActionReportForm.get(key.toString()).value?.length || 0;
}
<span> {{getStrLength(e.quesId)}} of 500 characters</span>
英文:

It's working script:

app.component.html
&lt;form [formGroup]=&quot;afterActionReportForm&quot;&gt;
  &lt;div  class=&quot;row&quot; *ngIf=&quot;reportList &amp;&amp; reportList.length &gt; 0&quot; style=&quot;padding:10px;&quot;&gt;
    &lt;div *ngFor=&quot;let e of reportList; let i = index&quot; class=&quot;col-sm-6&quot; style=&quot;margin-top: 2em;&quot;&gt;
        {{i+1}}. {{e.question}}
        &lt;textarea style=&quot;width:100%&quot; #{{e.quesId}} rows=&quot;8&quot; cols=&quot;75&quot; maxlength=&quot;500&quot; [formControlName]=&quot;e.quesId&quot;
        class=&quot;form-control&quot;  pInputTextArea &gt;&lt;/textarea&gt;
        &lt;span&gt; {{afterActionReportForm.get(e.quesId.toString()).value.length}} of 500 characters&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;/form&gt;

app.component.ts

  ngOnInit() {
    this.afterActionReportForm = new FormGroup({});
    this.reportList = this.data.reportList;
    for (let i = 0; i &lt; this.reportList.length; i++) {
        const key = this.reportList[i].quesId+&#39;&#39;;
        this.afterActionReportForm.addControl(key, new FormControl(this.reportList[i].boardAnswers));
    }
  }

And more better create method for counting length

getStrLength(key: string | number): number {
    return this.afterActionReportForm.get(key.toString()).value?.length || 0;
  }

&lt;span&gt; {{getStrLength(e.quesId)}} of 500 characters&lt;/span&gt;

答案2

得分: 1

我有同样的需求。我使用了getter方法 this.f 来获取表单控件。将当前的 quesId 与控件对象中的ID进行比较,以获取值和长度。这对我有效。

HTML

<form [formGroup]="afterActionReportForm">
  <div class="row" *ngIf="reportList && reportList.length > 0" style="padding: 10px;">
    <div *ngFor="let e of reportList; let i = index" class="col-sm-6" style="margin-top: 2em;">
      {{i+1}}. {{e.question}}
      <textarea style="width: 100%" #{{e.quesId}} rows="8" cols="75" maxlength="500" [formControlName]="e.quesId" class="form-control" pInputTextArea></textarea>
      <span>{{getMyLength(e.quesId)}} of 500 characters</span>
    </div>
  </div>
</form>

TS

get f() { return this.afterActionReportForm.controls; }

getMyLength(id) {
  var len;
  Object.entries(this.f).forEach(([key, value]) => {
    if (key === id) {
      len = value.value.length;
    }
  });
  return len;
}

如果您有任何其他问题,请随时提出。

英文:

I had same requirement. I used the getter method this.f to fetch the form controls. Compared the current quesId with the id from the object of controls to get the value and length. This works for me

Html

    &lt;form [formGroup]=&quot;afterActionReportForm&quot;&gt;
    &lt;div  class=&quot;row&quot; *ngIf=&quot;reportList &amp;&amp; reportList.length &gt; 0&quot; style=&quot;padding:10px;&quot;&gt;
      &lt;div *ngFor=&quot;let e of reportList; let i = index&quot; class=&quot;col-sm-6&quot; style=&quot;margin-top: 2em;&quot;&gt;
          {{i+1}}. {{e.question}}
          &lt;textarea style=&quot;width:100%&quot; #{{e.quesId}} rows=&quot;8&quot; cols=&quot;75&quot; maxlength=&quot;500&quot;  [formControlName]=&quot;e.quesId&quot;
          class=&quot;form-control&quot;  pInputTextArea &gt;&lt;/textarea&gt;
          &lt;span &gt; {{getMyLength(e.quesId)}} of 500 characters&lt;/span&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  &lt;/form&gt;

TS

 get f() { return this.afterActionReportForm.controls; }
 

   getMyLength(id){
    var len;
  Object.entries(this.f).forEach(([key,value]) =&gt; {
    if(key === id){
     len= value.value.length;
    }
  });
  return len;
   }

huangapple
  • 本文由 发表于 2020年9月17日 23:55:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/63941835.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定