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
相关产品推荐
相关产品推荐

