Tìm kiếm trang web

html - Giá trị của control trong biểu mẫu phản ứng của Angular chỉ là những gì người dùng gõ?


Tôi có một biểu mẫu phản ứng mà tôi đang cố gắng lấy giá trị và gán nó cho một biến có kiểu được định nghĩa trong một giao diện. Tuy nhiên, biểu mẫu này được điền bằng API Google Places (vì vậy tất cả các điều khiển biểu mẫu đều bị vô hiệu hóa và không thể chỉnh sửa bởi người dùng, ngoại trừ điều khiển biểu mẫu đầu tiên - điều khiển đó là trường mà người dùng nhập địa chỉ ban đầu).

Dạng phản ứng như sau:

ngOnInit() {
    // Initialization of branch Address reactive form (Form 2 - Step 2)
    this.addBranchAddressReactiveForm();
  }

// Form Group 2 - Branch Address (Step 2)
  addBranchAddressReactiveForm() {
    this.addBranchAddressForm = this.fb.group({
      // Branch Address Control
      branchAddress: ['',
        Validators.compose([Validators.required])
      ],
      // Branch Street Name Control
      branchStreetName: [{value: '', disabled: true},
        Validators.compose([Validators.required])
      ],
      // Branch Suburb Control
      branchSuburb: [{value: '', disabled: true},
        Validators.compose([Validators.required])
      ] ,
      // Branch City Control
      branchCity: [{value: '', disabled: true},
        Validators.compose([Validators.required])
      ],
      // Branch Province Control
      branchProvince: [{value: '', disabled: true},
        Validators.compose([Validators.required])
      ],
      // Branch Country Control
      branchCountry: [{value: '', disabled: true},
        Validators.compose([Validators.required])
      ],
      // Branch ZIP Control
      branchZip: [{value: '', disabled: true},
        Validators.compose([Validators.required])
      ]
    });
  }

Như có thể thấy ở trên, tất cả các điều khiển ngoại trừ điều khiển đầu tiên (branchAddress) đều bị vô hiệu hóa - vì các điều khiển này được điền khi lựa chọn địa chỉ. Khi nhìn vào biểu mẫu trong file component.html, bạn có thể thấy rằng các "giá trị" được gán một cách động (vì các giá trị này thay đổi tùy thuộc vào địa chỉ được chọn):

<form [formGroup]="addBranchAddressForm">
            <ng-template matStepLabel>Enter New Branch Address</ng-template>
            <div class="new-branch-form-container">

              <!-- Main Branch Address Parameter (Input that generates the autocomplete dropdown list) -->
              <mat-form-field>
                <mat-label>Enter New Branch Address</mat-label>
                <input matInput placeholder="Enter a location" formControlName="branchAddress" ngx-google-places-autocomplete #placesRef="ngx-places" [options]="addressOptions" (onAddressChange)="handleAddressChange($event)"/>
                <mat-hint>Enter the address of the new branch and select the appropriate address item</mat-hint>
                <mat-error>Please enter the new branch’s address</mat-error>
              </mat-form-field>

              <!-- Branch Street Name (Autofilled) -->
              <mat-form-field>
                <mat-label>Street Name</mat-label>
                <input matInput formControlName="branchStreetName" readonly value={{streetName}}>
                <mat-hint>The street name of the address selected</mat-hint>
                <mat-error>Please enter the street name of the address specified</mat-error>
              </mat-form-field>
              <br>

              <!-- Branch Suburb (Autofilled) -->
              <mat-form-field>
                <mat-label>Suburb</mat-label>
                <input matInput formControlName="branchSuburb" readonly value={{suburb}}>
                <mat-hint>The suburb of the address selected</mat-hint>
                <mat-error>Please enter a valid suburb</mat-error>
              </mat-form-field>
              <br>

              <!-- Branch City (Autofilled) -->
              <mat-form-field>
                <mat-label>City / Town</mat-label>
                <input matInput formControlName="branchCity" readonly value={{city}}>
                <mat-hint>The city of the address selected</mat-hint>
                <mat-error>Please enter a valid city</mat-error>
              </mat-form-field>

              <!-- Branch Province (Autofilled) -->
              <mat-form-field>
                <mat-label>Province</mat-label>
                <input matInput formControlName="branchProvince" readonly value="{{province}}">
                <mat-hint>The province of the address selected</mat-hint>
                <mat-error>Please enter the province of the address specified</mat-error>
              </mat-form-field>
              <br>

              <!-- Branch Country (Autofilled) -->
              <mat-form-field>
                <mat-label>Country</mat-label>
                <input matInput formControlName="branchCountry" readonly value={{country}}>
                <mat-hint>The country of the address selected</mat-hint>
                <mat-error>Please enter the country of the address specified</mat-error>
              </mat-form-field>
              <br>

              <!-- Branch ZIP (Autofilled) -->
              <mat-form-field>
                <mat-label>ZIP</mat-label>
                <input matInput formControlName="branchZip" readonly value={{zip}}>
                <mat-hint>The ZIP / Postal code of the address selected</mat-hint>
                <mat-error>Please enter the ZIP / Postal code of the address specified</mat-error>
              </mat-form-field>
              <br>
            </div>

            <!-- Button to navigate to previous step in stepper -->
            <button mat-stroked-button matStepperPrevious color="primary">Back</button>

            <!-- Button to navigate to next step in stepper (disabled until branch address form is valid) -->
            <button mat-stroked-button matStepperNext color="primary" [disabled]="!addBranchAddressForm.valid">Next</button>
          </form>

Vấn đề của tôi như sau. Tôi muốn có thể gán các giá trị từ biểu mẫu này cho một đối tượng để tôi có thể tạo một bản ghi trong cơ sở dữ liệu bằng cách liên kết với API web (không quan trọng) - mặc dù, khi cố gắng gán giá trị của biểu mẫu này cho biến, duy nhất 'giá trị' được truyền chỉ là những gì người dùng tự nhập. Ví dụ, như có thể thấy dưới đây, người dùng nhập '12' trước khi chọn một địa chỉ.

Giá trị "12" này sẽ là giá trị duy nhất được mã dưới đây ghi lại (mặc dù các điều khiển còn lại đã được điền sau khi chọn địa chỉ):

const branch: Branch = this.addBranchDetailsForm.value;

Vì vậy, khi ghi lại 'branch' ở trên, kết quả đầu ra sẽ như sau, và không phải là một đối tượng chứa tất cả các giá trị tìm thấy trong từng điều khiển biểu mẫu riêng biệt:

Tôi đang điền các giá trị điều khiển biểu mẫu như sau:

public handleAddressChange(address: any) {

    // Full unformatted address (Not Displayed)
    this.address = address.formatted_address;
    console.log(this.address);

    // Place id (Not Displayed)
    this.placeId = address.place_id;
    console.log(this.placeId);

    // Latitude coordinate (Not Displayed)
    this.latitude = address.geometry.location.lat();
    console.log(this.latitude);

    // Longitude coordinate (Not Displayed)
    this.longitude = address.geometry.location.lng();
    console.log(this.longitude);

    // Reset street address on method refresh
    this.streetName = "";

    // Street number (Displayed i.t.o)
    for (var i = 0; i < address.address_components.length; i++) {
      for (var x = 0; x < address.address_components[i].types.length; x++) {
        if (address.address_components[i].types[x] === "street_number") {
          this.streetName = JSON.parse(JSON.stringify(address.address_components[i].long_name)) + " ";
        }
      }
    }

    // Street name (Displayed i.t.o)
    for (var i = 0; i < address.address_components.length; i++) {
      for (var x = 0; x < address.address_components[i].types.length; x++) {
        if (address.address_components[i].types[x] === "route") {
          this.streetName += JSON.parse(JSON.stringify(address.address_components[i].long_name));
        }
      }
    }

    // Reset suburb on method refresh
    this.suburb = "";

    // Suburb (Displayed)
    for (var i = 0; i < address.address_components.length; i++) {
      for (var x = 0; x < address.address_components[i].types.length; x++) {
        if (address.address_components[i].types[x] === "sublocality") {
          this.suburb = JSON.parse(JSON.stringify(address.address_components[i].long_name))
        }
      }
    }

    // Reset city on method refresh
    this.city = "";

    // City (Displayed)
    for (var i = 0; i < address.address_components.length; i++) {
      for (var x = 0; x < address.address_components[i].types.length; x++) {
        if (address.address_components[i].types[x] === "locality") {
          this.city = JSON.parse(JSON.stringify(address.address_components[i].long_name))
        }
      }
    }

    // Reset province on method refresh
    this.province = "";

    // Province (Displayed)
    for (var i = 0; i < address.address_components.length; i++) {
      for (var x = 0; x < address.address_components[i].types.length; x++) {
        if (address.address_components[i].types[x] == "administrative_area_level_1") {
          this.province = JSON.parse(JSON.stringify(address.address_components[i].long_name))
        }
      }
    }

    // Reset country on method refresh
    this.country = "";

    // Country (Displayed)
    for (var i = 0; i < address.address_components.length; i++) {
      for (var x = 0; x < address.address_components[i].types.length; x++) {
        if (address.address_components[i].types[x] == "country") {
          this.country = JSON.parse(JSON.stringify(address.address_components[i].long_name))
        }
      }
    }

    // Reset zip on method refresh
    this.zip = "";

    // ZIP (Displayed)
    for (var i = 0; i < address.address_components.length; i++) {
      for (var x = 0; x < address.address_components[i].types.length; x++) {
        if (address.address_components[i].types[x] == "postal_code") {
          this.zip = JSON.parse(JSON.stringify(address.address_components[i].long_name))
        }
      }
    }
  }

Phương thức handleAddressChange nhận địa chỉ được nhập trong điều khiển (trường) đầu tiên của biểu mẫu như được thấy dưới đây:

<!-- Main Branch Address Parameter (Input that generates the autocomplete dropdown list) -->
              <mat-form-field>
                <mat-label>Enter New Branch Address</mat-label>
                <input matInput placeholder="Enter a location" formControlName="branchAddress" ngx-google-places-autocomplete #placesRef="ngx-places" [options]="addressOptions" (onAddressChange)="handleAddressChange($event)"/>
                <mat-hint>Enter the address of the new branch and select the appropriate address item</mat-hint>
                <mat-error>Please enter the new branch’s address</mat-error>
              </mat-form-field>

Khi phương pháp này được kích hoạt, các biến như đã thấy ở trên (ví dụ: this.suburb/this.city) được điền đầy - và do đó các biến này được hiển thị như một phần của thuộc tính value trong trường nhập liệu tương ứng. Ví dụ:

<!-- Branch Suburb (Autofilled) -->
              <mat-form-field>
                <mat-label>Suburb</mat-label>
                <input matInput formControlName="branchSuburb" readonly value={{suburb}}>
                <mat-hint>The suburb of the address selected</mat-hint>
                <mat-error>Please enter a valid suburb</mat-error>
              </mat-form-field>
              <br>

Ở trên bạn có thể thấy rằng biến (this.suburb) được gán với thuộc tính giá trị là {{suburb}}..

Bất kỳ lý do nào về việc tại sao điều này có thể xảy ra đều được đánh giá cao. Cảm ơn bạn đã dành thời gian.

Câu trả lời #1

Vì có các trường bị vô hiệu hóa, formGroup.value sẽ không trả về các giá trị này. Bạn sẽ cần gọi phương thức getRawValue() của formGroup để lấy giá trị của trường bất kể trạng thái bật/tắt của chúng.

Bạn cần làm điều này:

const branch: Branch = this.addBranchDetailsForm.getRawValue();

Từ tài liệu Angular: https://angular.io/api/forms/FormGroup#getRawValue

getRawValue() - Lấy tất cả các giá trị bất kể trạng thái bị vô hiệu hóa. Thuộc tính value là cách tốt nhất để lấy giá trị của nhóm, vì nó loại trừ các điều khiển bị vô hiệu hóa trong FormGroup.

Rõ ràng từ mã cập nhật của bạn rằng bạn không đặt giá trị formGroup và do đó bạn nhận được các giá trị trống mặc dù sử dụng phương thức getRawValue(). Ở đây bạn không cập nhật formControl.

 this.streetName = JSON.parse(JSON.stringify(address.address_components[i].long_name)) + " ";

Bạn cần thay đổi cái này thành:

this. addBranchDetailsForm.get('branchStreetName').setValue(JSON.stringify(address.address_components[i].long_name)) + " ";

Điều tương tự áp dụng cho tất cả các lĩnh vực khác.

Bài viết liên quan