AngularJS 1.6输入组件双向绑定:判断值变更避免无效保存
我之前也遇到过类似的AngularJS组件绑定时机的问题,不用$watch完全可以解决,核心是先搞定初始值的正确获取——你在子组件$onInit里拿不到值,是因为父组件的userDataObject是异步从服务器加载的,子组件初始化时这个数据还没回来,所以fieldValue是undefined。
给你两个最直接的方案:
方案一:父组件传递初始值,子组件用$onChanges捕获
既然父组件最终会拿到完整的初始数据,那我们直接把初始值单独传给子组件,利用AngularJS的$onChanges钩子来捕获初始值的变化(当父组件异步数据加载完成后,这个绑定值会更新,触发$onChanges)。
- 修改父组件模板,新增
initial-field-value的单向绑定:
<parent-component> <child-component save-value="$ctrl.saveToDB()" field-value="$ctrl.userDataObject.userInformation.firstName" initial-field-value="$ctrl.userDataObject.userInformation.firstName"> </child-component> </parent-component>
- 更新子组件的
bindings,添加初始值的单向绑定:
bindings: { fieldValue: '=', saveValue: '&', initialFieldValue: '<' // 单向绑定,只接收父组件传递的初始值 }
- 子组件控制器里保存初始值,并在点击时对比:
function ChildController() { let initialValue; this.$onChanges = (changes) => { // 只在initialFieldValue第一次有有效值时保存 if (changes.initialFieldValue && changes.initialFieldValue.currentValue !== undefined) { initialValue = changes.initialFieldValue.currentValue; } }; this.handleSave = () => { // 对比当前值和初始值,不同才触发保存 if (this.fieldValue !== initialValue) { this.saveValue(); // 保存后更新初始值,避免后续点击重复提交相同内容 initialValue = this.fieldValue; } }; }
- 子模板修改按钮点击事件:
<div> <input ng-model="$ctrl.fieldValue"> <button ng-click="$ctrl.handleSave()">OK</button> </div>
方案二:用ng-if延迟子组件渲染
通过ng-if让子组件只有在父组件的userDataObject加载完成后才初始化,这样子组件的$onInit就能直接拿到有效的fieldValue了。
- 修改父组件模板,添加
ng-if:
<parent-component> <child-component ng-if="$ctrl.userDataObject" <!-- 只有数据加载完成才渲染子组件 --> save-value="$ctrl.saveToDB()" field-value="$ctrl.userDataObject.userInformation.firstName"> </child-component> </parent-component>
- 子组件控制器直接在
$onInit里保存初始值:
function ChildController() { let initialValue; this.$onInit = () => { // 因为ng-if的存在,此时fieldValue已经是父组件加载完成的初始值 initialValue = this.fieldValue; }; this.handleSave = () => { if (this.fieldValue !== initialValue) { this.saveValue(); initialValue = this.fieldValue; } }; }
- 子模板同样修改按钮点击事件为
handleSave即可。
这两个方案都完全避开了$watch,逻辑直接清晰。方案一更灵活,适合子组件可能在数据加载前就渲染的场景;方案二更简洁,适合可以延迟子组件渲染的情况。
内容的提问来源于stack exchange,提问作者NbonD
相关产品推荐
相关产品推荐

