You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular双向绑定下子组件Input值不更新 编辑后切换选中对象输入框不刷新

问题原因
  • 表单控件没有和组件属性做双向绑定,仅通过插值语法给value属性赋值,属于单向渲染。用户手动修改输入框内容后,浏览器会更新DOM的实际值,此时Angular不会主动将新的模型值同步到已经被用户修改过的DOM节点上,你代码中的title输入框甚至没有配置value属性,完全没有初始值绑定逻辑。
  • 子组件没有监听@Input() editedOfferId的变化,仅在构造函数中执行了一次选中对象的查询,后续父组件切换选中ID时,子组件内部的selectedOffer不会自动更新,也不会触发表单值的重置逻辑。
  • 编辑后的表单值没有同步回共享服务的对象中,修改仅停留在DOM层面,没有和底层数据关联。
修复方案

第一步:监听输入参数变化,自动更新选中对象

修改子组件的ts代码,给editedOfferId添加setter,每次参数变化时重新从服务查询最新对象:

@Component({
  selector: 'app-detail3',
  templateUrl: './detail3.component.html',
  styleUrls: ['./detail3.component.css']
})
export class Detail3Component implements OnInit {

  private _editedOfferId: number = -1;
  @Input() set editedOfferId(id: number) {
    this._editedOfferId = id;
    if (id !== -1) {
      this.selectedOffer = this.service.findById(id)!;
    }
  }
  get editedOfferId() {
    return this._editedOfferId;
  }
  @Output() editedOfferChanged = new EventEmitter<number>();

  public selectedOffer: Offer = new Offer("", "", new Date(), AuctionStatus.NEW, 0);

  status = AuctionStatus
  keys: Array<number>;

  constructor(public service: OffersService) {
    this.keys = Object.keys(this.status).filter(k => !isNaN(Number(k))).map(Number);
  }

  ngOnInit(): void {
  }

  // 实现缺失的checkObjectChanged方法,同步修改到服务/触发父组件更新
  public checkObjectChanged() {
    this.editedOfferChanged.emit(this._editedOfferId);
  }
}

第二步:给表单控件添加双向绑定,实现数据自动同步

首先要在组件所属的模块中导入FormsModule:

// 对应模块文件,比如app.module.ts
import { FormsModule } from '@angular/forms';

@NgModule({
  imports: [
    // 其他导入
    FormsModule
  ]
})

然后修改子组件模板,把所有表单控件的value、selected属性替换为[(ngModel)]双向绑定:

<div id="content" *ngIf="editedOfferId != -1">
  <div id="data-table">
    <table>
      <tr>
        <th scope="row" colspan="2">Selected offer details(id = {{selectedOffer.id}})</th>
      </tr>
      <tr>
        <th scope="row">Title:</th>
        <td><input type="text" id="txtTitle" [(ngModel)]="selectedOffer.title" (input)="checkObjectChanged()"></td>
      </tr>
      <tr>
        <th scope="row">Description:</th>
        <td><input type="text" id="txtDescription" [(ngModel)]="selectedOffer.description" (input)="checkObjectChanged()"></td>
      </tr>
      <tr>
        <th scope="row">Status:</th>
        <td>
          <select (input)="checkObjectChanged()" id="txtStatus" [(ngModel)]="selectedOffer.auctionStatus">
            <option *ngFor="let key of keys" [ngValue]="key" [value]="status[key]" [label]="status[key]"></option>
          </select>
        </td>
      </tr>
      <tr>
        <th scope="row">Highest Bid:</th>
        <td><input id="txtHighestBid" [(ngModel)]="selectedOffer.valueHighestBid" (input)="checkObjectChanged()"></td>
      </tr>
    </table>
  </div>
</div>
<div *ngIf="editedOfferId == -1">
  <label  id="lblNothingSelected">Nothing has been selected yet</label>
</div>

修改后每次切换选中ID时,selectedOffer会自动更新,ngModel会自动把最新的对象属性同步到表单控件上,用户编辑的内容也会自动同步回selectedOffer对象,因为是引用类型,共享服务里的对应对象也会同步更新。

内容的提问来源于stack exchange,提问作者A. Vreeswijk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 16:57:05