编辑DataTable行时无法为p-autocomplete设置FormGroup值
It looks like the core issue here is that PrimeNG's p-autocomplete has specific behavior when paired with forceSelection="true" and the field property—unlike standard form controls, it often expects a matching object from your suggestions array to display the selected value correctly, not just a raw string. Let's walk through the fixes step by step:
1. Mismatched Value Type (String vs. Object)
Your autocomplete is configured with field="value", meaning it uses the value property of objects in your cities array to render options. When you set city: c.mdPostalCd.city in setValue(), you're passing a plain string—but the component needs the full matching object from cities to display the selection.
Fix: Bind to the Matching Object Instead of a String
Update your onRowEdit method to locate the corresponding city object in your suggestions array and pass that to the form control:
onRowEdit(c: UserAddr) { this.valid = false; // Find the city object that matches the stored city value const selectedCity = this.cities.find(city => city.value === c.mdPostalCd.city); this.userAddrForm.setValue({ mgAddrId: c.mgAddrId, lineA: c.lineA, lineB: c.mdPostalCd.area, lineC: c.mdPostalCd.suburb, city: selectedCity, // Pass the full object here province: c.province, zipcode: c.mdPostalCd.zipCd }); this.index = this.addresses.indexOf(c); this.displayDialog = true; }
2. Ensure the City Exists in Suggestions (For forceSelection=true)
Since forceSelection="true" is enabled, the autocomplete will only display a value if it exists in the cities array. If your suggestions load asynchronously (via completeMethod), the target city might not be present when you open the edit dialog.
Fix: Preload or Add the Target City to Suggestions
If the city isn't already in your cities array, add it before setting the form value to satisfy the forceSelection requirement:
onRowEdit(c: UserAddr) { this.valid = false; const targetCityValue = c.mdPostalCd.city; // Add the city to suggestions if it doesn't exist const cityExists = this.cities.some(city => city.value === targetCityValue); if (!cityExists) { this.cities.push({ value: targetCityValue }); // Match your cities object structure } // Grab the matching object and set it to the form const selectedCity = this.cities.find(city => city.value === targetCityValue); this.userAddrForm.setValue({ mgAddrId: c.mgAddrId, lineA: c.lineA, lineB: c.mdPostalCd.area, lineC: c.mdPostalCd.suburb, city: selectedCity, province: c.province, zipcode: c.mdPostalCd.zipCd }); this.index = this.addresses.indexOf(c); this.displayDialog = true; }
3. Force View Update If Change Detection Lags
Occasionally, Angular's change detection doesn't pick up the form value change immediately for the autocomplete component. You can manually trigger it using ChangeDetectorRef:
Step 1: Inject ChangeDetectorRef
import { ChangeDetectorRef } from '@angular/core'; constructor(private cdr: ChangeDetectorRef) {}
Step 2: Trigger Detection After Setting Form Value
onRowEdit(c: UserAddr) { // ... (previous code to find selectedCity and set form values) this.userAddrForm.setValue({ ... }); this.cdr.detectChanges(); // Force Angular to update the autocomplete view this.displayDialog = true; }
Quick Sanity Check: Verify Your cities Structure
Double-check that your cities array matches the structure expected by the autocomplete. For example, if you're using field="value", your array should look like this:
cities = [ { value: 'New York' }, { value: 'London' }, { value: 'Paris' } ];
If your objects use a different property name (like name instead of value), update the field attribute in your HTML to match:
<p-autocomplete [suggestions]="cities" [forceSelection]="true" formControlName="city" field="name" ...></p-autocomplete>
内容的提问来源于stack exchange,提问作者Varma GRK

