Angular 4中为输入控件赋值Null抛出异常的解决方法
嘿,我完全懂你碰到的问题——当下拉列表没选中值时,fedExTax返回null,结果模板里访问.value直接抛出空指针异常,对吧?咱们可以用几个简单的办法解决这个问题,让输入控件在未选择状态下显示为空,同时避免报错:
方案1:给getter返回一个空的默认对象(最推荐)
修改你的fedExTax getter,当未选择下拉值时,返回一个带有空value属性的空对象,而不是null。这样模板绑定的时候永远不会遇到null,自然就不会报错,输入框也会显示为空:
get fedExTax(): BackendDto.FedExciseExpense { if (this.currentSelectedCoveragePolicy != 0) { return this.fedExciseExpensesInputs.find(x => x.coveragePolicyTypeId == this.currentSelectedCoveragePolicy && x.is953D == this.currentSelected953D ); } // 返回一个符合类型的空对象,确保value存在且为空 return { value: '' } as BackendDto.FedExciseExpense; }
这个方法的好处是从数据源层面解决了问题,模板不需要做任何修改,双向绑定也能正常工作——用户输入内容时,值会正确赋值到这个空对象的value属性里,后续你可以根据需要把这个对象合并到你的数据源中。
方案2:在模板中使用安全导航操作符
如果你不想修改组件逻辑,可以在模板里用Angular的安全导航符?.来避免空指针异常,把[(ngModel)]="fedExTax.value"改成[(ngModel)]="fedExTax?.value":
<input type="text" class="form-control form-control-sm" [(ngModel)]="fedExTax?.value" [ngModelOptions]="{standalone: true}" name="{{FedExciseKey}}" numberFormat="numberPercent:.0-2" (ngModelChange)="change()" [required]="true" tooltip="{{'CAPTIVES.LINES.INCCAPTIVEEXPENSE.' + FedExciseKey + 'TOOLTIP'|uppercase|translate}}" placement="bottom">
不过要注意:当fedExTax为null时,用户输入的内容无法直接赋值给fedExTax.value(因为对象不存在),所以你需要在change()方法里额外处理这种情况——比如创建一个新的FedExciseExpense实例,赋值后添加到fedExciseExpensesInputs数组中。
方案3:条件渲染输入框
如果需求允许,你也可以在未选择下拉值时,渲染一个空的、禁用的输入框,或者干脆不渲染输入框:
<!-- 选中时显示正常输入框 --> <div class="col-lg-3 col-6 mb-3" *ngIf="currentSelectedCoveragePolicy != 0"> <label class="col-form-label">{{'CAPTIVES.LINES.INCCAPTIVEEXPENSE.' + FedExciseKey|uppercase|translate}}</label> <div class="input-group"> <input type="text" class="form-control form-control-sm" [(ngModel)]="fedExTax.value" [ngModelOptions]="{standalone: true}" name="{{FedExciseKey}}" numberFormat="numberPercent:.0-2" (ngModelChange)="change()" [required]="true" tooltip="{{'CAPTIVES.LINES.INCCAPTIVEEXPENSE.' + FedExciseKey + 'TOOLTIP'|uppercase|translate}}" placement="bottom"> <span class="input-group-addon">%</span> </div> </div> <!-- 未选中时显示空的禁用输入框 --> <div class="col-lg-3 col-6 mb-3" *ngIf="currentSelectedCoveragePolicy == 0"> <label class="col-form-label">{{'CAPTIVES.LINES.INCCAPTIVEEXPENSE.' + FedExciseKey|uppercase|translate}}</label> <div class="input-group"> <input type="text" class="form-control form-control-sm" placeholder="" disabled> <span class="input-group-addon">%</span> </div> </div>
这个方案适合不需要用户在未选择下拉时输入内容的场景。
综合来看,方案1是最省心的,既能满足输入框显示为空的需求,又能保证双向绑定的正常工作,不需要额外处理模板或事件逻辑。
内容的提问来源于stack exchange,提问作者Tom

