【问题标题】:Angular form clone does not submit data. But the parent form doesAngular 表单克隆不提交数据。但是父表单确实
【发布时间】:2020-10-29 23:00:47
【问题描述】:

我正在做一个 Angular 项目,根据第一个表格中的债务人数量克隆一个表。因此,假设第一个表格需要 3 个债务人,下一个表格将生成 3 个表格。但是,当您尝试从克隆的表单中保存数据时,它不起作用,但第一个表单仅适用于克隆的来源。

  **MY TS FILE**
import { Component, OnInit } from "@angular/core";
import { FormGroup, FormBuilder, Validators } from "@angular/forms";
import { HttpClient } from "@angular/common/http";
import { Router } from "@angular/router";
import * as $ from 'jquery';


@Component({
selector: "app-annex",
templateUrl: "./annex.component.html",
styleUrls: ["./annex.component.css"],
})
export class AnnexComponent implements OnInit {
annexform: FormGroup;
id: any;
data = [];
decreaseDebtor: number;
alert: boolean = false;
alertUnsuccesful: boolean = false;
// annexForm: boolean = true;
// debtors_included: number;
myDebtors: any;
debtorsCount = 0;
// submitted = false;
// myDebtorsSubmit : number;
constructor(
 public fb: FormBuilder,
 private http: HttpClient,
 private router: Router
) {
 this.annexform = this.fb.group({
   debtor_name: ["", Validators.required],
   debtor_contact_person: ["", Validators.required],
   debtor_function: ["", Validators.required],
   debtor_address: ["", Validators.required],
   debtor_email: ["", [Validators.required, Validators.email]],
   debtor_phone_number: ["", Validators.required],
   debtor_proposed_limit: ["", Validators.required],
   debtor_invoice_term: ["", Validators.required],
   debtor_projected_turnover: ["", Validators.required],
   debtor_ledger: [null, Validators.required],
   client: Number,
 });
}
uploadLedgerFile(event: { target: HTMLInputElement }) {
 const file = (event.target as HTMLInputElement).files[0];
 this.annexform.patchValue({
   debtor_ledger: file,
 });
 this.annexform.get("debtor_ledger").updateValueAndValidity();
}

// convenience getter for easy access to form fields
get f() {
 return this.annexform.controls;
}

submitAnnexForm() {
 console.log(this.annexform.value)
 if (this.annexform.invalid) {
   return;
 }
 let formData: any = new FormData();
 formData.append("debtor_name", this.annexform.get("debtor_name").value);
 formData.append(
   "debtor_contact_person",
   this.annexform.get("debtor_contact_person").value
 );
 formData.append(
   "debtor_function",
   this.annexform.get("debtor_function").value
 );
 formData.append(
   "debtor_address",
   this.annexform.get("debtor_address").value
 );
 formData.append("debtor_email", this.annexform.get("debtor_email").value);
 formData.append(
   "debtor_phone_number",
   this.annexform.get("debtor_phone_number").value
 );
 formData.append("debtor_proposed_limit", this.annexform.get("debtor_proposed_limit").value);
 formData.append("debtor_invoice_term", this.annexform.get("debtor_invoice_term").value);
 formData.append("debtor_projected_turnover", this.annexform.get("debtor_projected_turnover").value);
 formData.append("debtor_ledger", this.annexform.get("debtor_ledger").value);
 formData.append("client", localStorage.getItem("id"));
 return this.http
   .post<{ id: string }>("http://127.0.0.1:8000/api/annex/", formData)
   .subscribe(
     (result) => {
       console.log(result); 
ngOnInit() {
 let retrievedObject = localStorage.getItem("id");
 console.log(retrievedObject);
 this.http
   .get<any>(`http://127.0.0.1:8000/api/create-client/${retrievedObject}/`)
   .subscribe(
     (res) => {
       this.decreaseDebtor = res.debtors_included;
       localStorage.setItem("debtors_included", res.debtors_included);
       this.myDebtors = JSON.parse(localStorage.getItem("debtors_included"));
       this.debtorsCount = JSON.parse(localStorage.getItem("debtors_count"));
       console.log(this.decreaseDebtor);
       console.log(this.myDebtors);
     },
     (error) => console.log(error)
   );
 $(document).ready(function () {
   let debtors = JSON.parse(localStorage.getItem("debtors_included"));
   let e = $(".rowToClone");
   for (let i = 0; i <= debtors-2; i++) {
     e.clone().insertAfter(e)
   }
 $(document).find(".rowToClone").trigger("create")
 });
}
}
  

这是我的 HTML 文件

      <div id="myDiv">
        <form class="rowToClone table-form" name="annexForm" [formGroup]="annexform" (ngSubmit)="submitAnnexForm($event)" onsubmit="event.preventDefault()" >
          <table class="table">
            <!--Table body-->
            <tbody class="annex-body">
              <tr>
                <td class="table-input-data">
                  <input
                    class="my-input"
                    type="text"
                    formControlName="debtor_name"
                    required
                    id="debtor_name"
                  />
                </td>
                <td class="table-input-data">
                  <input
                    class="my-input"
                    type="text"
                    formControlName="debtor_contact_person"
                    required
                    id="debtor_contact_person"
                  />
                </td>
                <td class="table-input-data">
                  <input
                    class="my-input"
                    type="text"
                    class="table-head-data3"
                    formControlName="debtor_function"
                    required
                    id="debtor_function"
                  />
                </td>
                <td class="table-input-data">
                  <input
                    class="my-input"
                    type="text"
                    formControlName="debtor_address"
                    required
                    id="debtor_address"
                  />
                </td>
                <td class="table-input-data">
                  <input
                    class="my-input"
                    type="email"
                    formControlName="debtor_email"
                    required
                    id="debtor_email"
                  />
                </td>
                <td class="table-input-data">
                  <input
                    class="my-input"
                    type="text"
                    formControlName="debtor_phone_number"
                    required
                    id="debtor_phone_number"
                  />
                </td>
                <td class="table-input-data">
                  <input
                    class="my-input"
                    type="text"
                    formControlName="debtor_proposed_limit"
                    required
                    id="debtor_proposed_limit"
                  />
                </td>
                <td class="table-input-data">
                  <input
                    class="my-input"
                    type="text"
                    formControlName="debtor_invoice_term"
                    required
                    id="debtor_invoice_term"
                  />
                </td>
                <td class="table-input-data">
                  <input
                    class="my-input"
                    type="text"
                    formControlName="debtor_projected_turnover"
                    required
                    id="debtor_projected_turnover"
                  />
                </td>
                <td class="table-input-data">
                  <input
                    class="my-input"
                    id="debtor_ledger"
                    type="file"
                    (change)="uploadLedgerFile($event)"
                    required
                  />
                </td>
                <td class="table-input-data">
                  <button
                    class="my-input"
                    class="mybutton"
                    id="submit"
                    type="submit"
                  >
                    Save
                  </button>
                </td>
              </tr>
            </tbody>
            <!--Table body-->
          </table>
        </form>
      </div>

【问题讨论】:

    标签: javascript angular forms clone


    【解决方案1】:

    我在这里看到了一些问题。

    • 在对 POST 数据的 http 请求的订阅中调用了 ngInit 回调方法。这要么是副本和过去的错误,要么您确实需要将其移出该订阅。
    • 作为一般规则,Angular 不建议像您的代码那样直接操作 DOM。

    据我所知,

    • 您正在操纵 DOM,以便能够拥有响应使用事件的动态表单
    • 那么您正在尝试访问类中的这些克隆元素

    您克隆的表单在类中永远不可用的原因是因为您直接操作 DOM 而不是在类中创建对象。

    即克隆表单 DOM 元素不会使其在类中可用。

    如果您还没有通过 angular.io 上的 dynamic form walkthrough,您可能会受益。

    我建议嵌套 FormGroups 或使用 FormArray。以nestedFormGroups 为例,您可以按照以下方式做一些事情

    constructor(
     public fb: FormBuilder,
     private http: HttpClient,
     private router: Router
    ) {
      this.annexForm = this.fb.group( {
         vendor1: this.fb.group(this.getVendorFormFields() ),
         vendor1: this.fb.group(this.getVendorFormFields() )
      });
    }
    
    getVendorFormFields() {
      return {
        debtor_name: ["", Validators.required],
        debtor_contact_person: ["", Validators.required],
        debtor_function: ["", Validators.required],
        debtor_address: ["", Validators.required],
        debtor_email: ["", [Validators.required, Validators.email]],
        debtor_phone_number: ["", Validators.required],
        debtor_proposed_limit: ["", Validators.required],
        debtor_invoice_term: ["", Validators.required],
        debtor_projected_turnover: ["", Validators.required],
        debtor_ledger: [null, Validators.required],
        client: Number,
      };
    }
    

    这允许您为每个供应商保留特定的表单组,并允许您在 HTML 模板中隔离验证(如果您需要的话)。

    另一种可能使事情更容易管理的方法是创建一个VendorForm 组件。在此组件中,具有您需要的表单和任何验证。这将允许您从表单中分离获取/设置数据的逻辑。这种类型的分离使您的代码管理更加容易,并且可以让您更轻松地管理添加/删除供应商,并为每个供应商提供相同的表单输入控件。

    在单独的注释中,您可以通过在表单上使用form.getRawValue() 为自己节省一些代码。这将有效地执行您对所有 .appendData 方法所做的事情。它采用一种形式并返回一个包含名称/值对的 JSON 对象。然后,您可以将其传递到您的 HTTP 请求中。

    我认为这里的简短版本是您正在尝试做一些事情来“解决”角度来获得您想要的东西。我建议遵循 angular 提供的动态表单示例。应该没有任何理由像您当前那样操作 DOM。

    希望这对您有所帮助。祝你好运

    【讨论】:

      猜你喜欢
      • 2012-08-14
      • 1970-01-01
      • 2014-08-31
      • 2012-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多