有没有更好的方法来构建一个Angular 15响应式表单,其中输入数据来自API?

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

Is there a better way to structure an Angular 15 reactive form with inputs populating from an api?

问题

Angular 15 使用 FormGroup 的响应式表单

我正在查看文档,尝试构建一个具有 4 个输入字段的表单,这些字段使用 GET 数据填充,并在提交时通过 PUT 更新。它确实有效,但似乎有些冗长,我想知道是否有更好的方法。

以下是我的变量和构造函数:

adminForm: FormGroup;
parameters$: Observable<any[]>;

constructor(
@Inject("environment") public environment: IEnvironment,
private formBuilder: FormBuilder,
private adminService: AdminService
) { }

以及 ngOnInit:

ngOnInit() {

this.adminForm = this.formBuilder.group({
pendingTimeout: ['', Validators.required],
readyTimeout: ['', Validators.required],
processingTimeout: ['', Validators.required],
activeTimeout: ['', Validators.required]
});

this.parameters$ = this.adminService.getParameters();

this.parameters$.subscribe(p => {
console.log('p', p);
this.f['activeTimeout'].setValue(p[0].value);
this.f['pendingTimeout'].setValue(p[1].value);
this.f['processingTimeout'].setValue(p[2].value);
this.f['readyTimeout'].setValue(p[3].value);
})
}

一个 getter,用于减少 HTML 冗长性:

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

以及提交方法,配置为以正确的格式返回给 API:

submit() {
if (!this.adminForm.valid) {
return;
}
console.log(this.adminForm.value);
this.adminService.putParameters([
{
"name": "ActiveTimeout",
"value": this.adminForm.value.activeTimeout
},
{
"name": "PendingTimeout",
"value": this.adminForm.value.pendingTimeout
},
{
"name": "ProcessingTimeout",
"value": this.adminForm.value.processingTimeout
},
{
"name": "ReadyTimeout",
"value": this.adminForm.value.readyTimeout
}
]);
}

英文:

Angular 15 Reactive Form using FormGroup

I am going through the docs trying to build a form with 4 inputs that populate with GET data, and update on submit via PUT. And it works. But it seems verbose and I wonder if there is a better way.

Here are my variables and the constructor:

  adminForm: FormGroup;
  parameters$: Observable&lt;any[]&gt;;

  constructor(
    @Inject(&quot;environment&quot;) public environment: IEnvironment,
    private formBuilder: FormBuilder,
    private adminService: AdminService
  ) { }

and ngOnInit:

  ngOnInit() {

    this.adminForm = this.formBuilder.group({
      pendingTimeout: [&#39;&#39;, Validators.required],
      readyTimeout: [&#39;&#39;, Validators.required],
      processingTimeout: [&#39;&#39;, Validators.required],
      activeTimeout: [&#39;&#39;, Validators.required]
    });

    this.parameters$ = this.adminService.getParameters();

    this.parameters$.subscribe(p =&gt; {
      console.log(&#39;p&#39;, p);
      this.f[&#39;activeTimeout&#39;].setValue(p[0].value);
      this.f[&#39;pendingTimeout&#39;].setValue(p[1].value);
      this.f[&#39;processingTimeout&#39;].setValue(p[2].value);
      this.f[&#39;readyTimeout&#39;].setValue(p[3].value);
    })
  }

A getter, to make the html less verbose:

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

and the submit method, configured so it returns to the API in the proper format:

submit() {
    if (!this.adminForm.valid) {
      return;
    }
    console.log(this.adminForm.value);
    this.adminService.putParameters([
      {
        &quot;name&quot;: &quot;ActiveTimeout&quot;,
        &quot;value&quot;: this.adminForm.value.activeTimeout
      },
      {
        &quot;name&quot;: &quot;PendingTimeout&quot;,
        &quot;value&quot;: this.adminForm.value.pendingTimeout
      },
      {
        &quot;name&quot;: &quot;ProcessingTimeout&quot;,
        &quot;value&quot;: this.adminForm.value.processingTimeout
      },
      {
        &quot;name&quot;: &quot;ReadyTimeout&quot;,
        &quot;value&quot;: this.adminForm.value.readyTimeout
      }
    ]);
  }

答案1

得分: 1

你可以创建一个模型类,其中包含一个构造函数来接收结果参数,然后使用这个类对象来设置结果,而不是使用formControl['control'].value。一个示例可以是:

// 在一个单独的类中
export class AdminModel {
  public pendingTimeout: number;
  public readyTimeout: number;
  public processingTimeout: number;
  public activeTimeout: number;

  constructor(
    pendingTimeout: number,
    readyTimeout: number,
    processingTimeout: number,
    activeTimeout: number
  ){
    this.pendingTimeout = pendingTimeout,
    this.readyTimeout= readyTimeout,
    this.processingTimeout= processingTimeout,
    this.activeTimeout= activeTimeout
  }
}

// 在你的组件类中
adminForm: FormGroup;
admin: any;
parameters$: Observable<any[]>;

constructor(
  @Inject("environment") public environment: IEnvironment,
  private formBuilder: FormBuilder,
  private adminService: AdminService
) { }

ngOnInit() {
  this.adminForm = this.formBuilder.group({
    pendingTimeout: ['', Validators.required],
    readyTimeout: ['', Validators.required],
    processingTimeout: ['', Validators.required],
    activeTimeout: ['', Validators.required]
  });

  this.parameters$ = this.adminService.getParameters();

  this.parameters$.subscribe(p => {
    admin = new AdminModel(p[0].value, p[1].value, p[2].value, p[3].value);
  })
}

我认为这种方式更简洁,缺点是有重复的类,但这样更容易阅读和理解。希望对你有所帮助 :)

<details>
<summary>英文:</summary>

You can create a model class with a constructor to receive the result parameters, then use this Class Object to set the result instead of using the formControl[&#39;control&#39;].value
A example would be like:

    //In a separated class
    export class AdminModel {
      public pendingTimeout: number;
      public readyTimeout: number;
      public processingTimeout: number;
      public activeTimeout: number;
    
     constructor(
            pendingTimeout: number,
            readyTimeout: number,
            processingTimeout: number,
            activeTimeout: number
    ){
                this.pendingTimeout = pendingTimeout,
                this.readyTimeout= readyTimeout,
                this.processingTimeout= processingTimeout,
                this.activeTimeout= activeTimeout
    }

//in your component class

      adminForm: FormGroup;
      admin: any;
      parameters$: Observable&lt;any[]&gt;;
    
      constructor(
        @Inject(&quot;environment&quot;) public environment: IEnvironment,
        private formBuilder: FormBuilder,
        private adminService: AdminService
      ) { }


    ngOnInit() {
        this.adminForm = this.formBuilder.group({
          pendingTimeout: [&#39;&#39;, Validators.required],
          readyTimeout: [&#39;&#39;, Validators.required],
          processingTimeout: [&#39;&#39;, Validators.required],
          activeTimeout: [&#39;&#39;, Validators.required]
        });
    
        this.parameters$ = this.adminService.getParameters();
    
        this.parameters$.subscribe(p =&gt; {
          admin = new AdminModel(p[0].value,p[1].value,p[2].value,p[3].value);
        })
      }



I thinks is less verbose, the cons are the duplicated classes, but it&#39;s easyer to read and understand like that. I hope it helps :)

</details>



# 答案2
**得分**: 1

我们总是重复类似的代码时,需要考虑是否创建一个函数是否合适。

```typescript
// 返回一个 formGroup 的函数
createGroup(data: any = null) {
  data = data || {
    pendingTimeout: '',
    readyTimeout: '',
    processingTimeout: '',
    activeTimeout: ''
  };

  return this.formBuilder.group({
    pendingTimeout: [data.pendingTimeout, Validators.required],
    readyTimeout: [data.readyTimeout, Validators.required],
    processingTimeout: [data.processingTimeout, Validators.required],
    activeTimeout: [data.activeTimeout, Validators.required]
  });
}

我们可以使用以下方式:

this.adminForm = this.createGroup(); // 一个空的 FormGroup

或者

this.parameters$.subscribe(p => {
  const data = {
    activeTimeout: p[0].value,
    pendingTimeout: p[1].value,
    processingTimeout: p[2].value,
    readyTimeout: p[3].value
  };
  this.adminForm = this.createGroup(data);
});
英文:

Always we repeat similar code we need think if it's good or not create a function.

//function that return a formGroup
createGroup(data:any=null)
{
data=data || {pendingTimeout: &#39;&#39;,
readyTimeout: &#39;&#39;,
processingTimeout:&#39;&#39;,
activeTimeout:&#39;&#39;}
return this.formBuilder.group({
pendingTimeout: [data.pendingTimeout, Validators.required],
readyTimeout: [data.readyTimeout, Validators.required],
processingTimeout: [data.processingTimeout, Validators.required],
activeTimeout: [data.activeTimeout, Validators.required]
});
}

we can use

   this.adminForm=this.createGroup(); //&lt;--an empty FormGroup

Or

   this.parameters$.subscribe(p=&gt;{
const data={
activeTimeout: p[0].value,
pendingTimeout: p[1].value,
processingTimeout: p[2].value,
readyTimeout: p[3].value
}
this.adminForm=this.createGroup(data)
})

huangapple
  • 本文由 发表于 2023年6月8日 01:34:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76425798.html
匿名

发表评论

匿名网友

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

确定