如何在Angular响应式表单中创建计算字段?

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

How to create calculated field in angular reactive forms?

问题

我已经在我的应用程序中创建了一个表单。

mapForm = this.fb.group({
  name: ['', Validators.required],
  view: this.fb.group({
    width: ['', Validators.required],
    height: ['', Validators.required]
  })
});

在这个表单中,我正在创建一个类似下面的JSON:

{
  "name": "x",
  "view": {
    "width": "100%",
    "height": "100%"
  }
}

所以我的表单是:

<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
  <label>
    First Name:
    <input type="text" formControlName="firstName" required>
  </label>
 
  <div formGroupName="view">
    <h3>View</h3>

    <label>
      width:
      <input type="text" formControlName="width">
    </label>
    
    <label>
      height:
      <input type="text" formControlName="height">
    </label>
  </div>
</form>

但我想要将我的视图的宽度/高度值(100)和单位(%)属性分开为两个输入元素,并将它们合并为JSON。

<label>
  width:
  <input type="text" formControlName="width" value="100">
</label>
<label>
  unit:
  <input type="text" formControlName="unit" value="%">
</label>

但我的view.width将是 "100%"。我该如何做呢?

英文:

I have created a form in my application.

  mapForm = this.fb.group({
	name: [&#39;&#39;, Validators.required],
	view: this.fb.group({
	  width: [&#39;&#39;, Validators.required],
	  height: [&#39;&#39;, Validators.required]
	})
  });

In this form, I am creating a JSON like following:

  {
	name: &quot;x&quot;, 
	view:{ 
		width: &quot;100%&quot;, 
		height: &quot;100%&quot; 
	} 
  }

So my form is:

&lt;form [formGroup]=&quot;myForm&quot; (ngSubmit)=&quot;onSubmit()&quot;&gt;
  &lt;label&gt;
    First Name:
    &lt;input type=&quot;text&quot; formControlName=&quot;firstName&quot; required&gt;
  &lt;/label&gt;
 
   &lt;div formGroupName=&quot;view&quot;&gt;
    &lt;h3&gt;View&lt;/h3&gt;

		&lt;label&gt;
		  width:
		  &lt;input type=&quot;text&quot; formControlName=&quot;width&quot;&gt;
		&lt;/label&gt;
		
		&lt;label&gt;
		  height:
		  &lt;input type=&quot;text&quot; formControlName=&quot;height&quot;&gt;
		&lt;/label&gt;
	&lt;/div&gt;
 &lt;/form&gt;

But I want to seperate my view's width/height value (100) and unit (%) properties two input elements and join them in json.

	&lt;label&gt;
	  width:
	  &lt;input type=&quot;text&quot; formControlName=&quot;height&quot; value=&quot;100&quot;&gt;
	&lt;/label&gt;
	&lt;label&gt;
	  unit:
	  &lt;input type=&quot;text&quot; formControlName=&quot;unit&quot; value=&quot;%&quot;&gt;
	&lt;/label&gt;

But my view.width will be "100%". How can I do it?

答案1

得分: 1

submit(form)
{
if (form.valid)
{
result={
name:form.value.name,
view:{
width:form.value.width+form.value.widthUnit,
heigth:form.value.height+form.value.heightUnit
}
}
console.log(result)
}
}

如果要在.html中使用,只需连接,例如:

<div [style.height]="form.value.height+form.value.heightUnit"
[style.width]="form.value.width+form.value.widthUnit">
</div>

在提交之前,不需要让表单完全匹配您的JSON。

英文:

why not, in submit?

submit(form)
{
   if (form.valid)
   {
      result={
        name:form.value.name,
        view:{
           width:form.value.width+form.value.widthUnit,
           heigth:form.value.height+form.value.heightUnit
        }
      }
      console.log(result)
   }
}

If you want to use in .html just concat, e.g.

&lt;div [style.height]=&quot;form.value.height+form.value.heightUnit&quot;
     [style.width]=&quot;form.value.width+form.value.widthUnit&quot;&gt;
&lt;/div&gt;

It's not necesary that the form ajust exactly to your json until you submit it

答案2

得分: 0

我只能想象你可以创建额外的表单控件字段,然后在要合并的表单控件上使用.valueChangescombineLatest(),在订阅中更新这些已更新的表单控件的值。在响应式表单内部没有这样的功能。然而,除非你真的有理由在运行时合并它们,否则最好在检索表单值以发送到某个地方时再合并它们。

示例:

combineLatest(
  this.form.controls.width.valueChanges(), 
  this.form.controls.unit.valueChanges()
).pipe(takeUntil(this.destroyed$)) // 不要忘记取消订阅
 .subscribe(([width, unit]) => {
   this.form.controls.combinedWidth.setValue(`${width}${unit}`);
   // 如果你使用了onPush,这里也要调用markForCheck()
 });

你可以在表单初始化后立即执行这个操作。

英文:

I can only imagine that you can create extra form control fields, then use .valueChanges with combineLatest() on the form controls you want to join and in the subscription update the values of those updated form controls. There is no such functionality from within reactive forms. However, unless you really have a reason to do this merging on the fly, it's better to just merge them when you retrieve the form value to send it somewhere.

Example:

combineLatest(
  this.form.controls.width.valueChanges(), 
  this.form.controls.unit.valueChanges()
).pipe(takeUntil(this.destroyed$)) // don&#39;t forget to have unsubscription
 .subscribe(([width, unit]) =&gt; {
   this.form.controls.combinedWidth.setValue(`${width}${unit}`);
   // if you&#39;re using onPush, also markForCheck() here
 });

You can do this right after form was initialized.

huangapple
  • 本文由 发表于 2020年1月6日 19:22:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/59611235.html
匿名

发表评论

匿名网友

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

确定