我有一个包含各种输入,选项和选择的表单。表单分为几个组件的各个部分。例如:
order.orderInfo.customerName
order.orderInfo.address
order.model.size
order.model.options
order.trims.selectedTrims
如果Order = {}
,那么它会因未定义的错误而崩溃。我的第一个想法是使用elvis运算符,但Angular不允许你在赋值中使用它。到目前为止,我发现的唯一“解决方案”是根本不使用[(ngModel)]
语法糖,而是将所有内容分解为:
<input [ngModel]="order?.orderInfo?.customer_mtm" (ngModelChange)="order.orderInfo.customer_mtm=$event" customer_mtm type="text">
这就是事情,我必须做一些非常错误的事情,因为从来没有能够使用[(ngModel)]
语法没有多大意义,这就是我所在的地方我现在。
我是否应该将所有代码更改为[ngModel]/(ngModelChange)
语法,或者我应该在概念上出错吗?
答案 0 :(得分:2)
可能有一些方法可以解决这个问题,但是我已经看到了它的完成方式。
在控制器中,您将基础对象创建为常量。对你而言:
const ORDER_BASE = { someprop : 'somedefaultval', ... }
此基数应满足您以其他方式使用elvis运营商的所有要求。当你在构造函数中设置模型的值(而不是ngInit,或者你会得到未定义的错误)时,你会去:
this.order = Object.assign ( {}, ORDER_BASE );
(这会生成对象的副本,因此您不会将基本引用用作模型)。
或者,您使用factory-ish函数:
this.order = makeFreshOrder ( );
makeFreshOrder ( ) {
return Object.assign ( {}, ORDER_BASE );
}
这可以让你摆脱与elvis操作员的混乱,担心init上可用的属性,等等。
我尽量将标记中的逻辑保持在最低限度,并且在我工作过的几个地方,这是最好的做法。除了使用三元表达式(它变得笨拙)在标记中进行非常简单的决策/检查/验证之外,别做其他事情,在控制器中执行此操作。
(注意,基础对象可以是&#34; Order&#34;类的新实例...输入这种东西可能很有用)。
我实际上已经被告知,在标记中,&#34;如果您正在使用elvis运营商,那么您就会变得懒惰。&#34;不确定这种或那种方式,但我明白这一点。
答案 1 :(得分:1)
崩溃的原因是您正在访问order
对象(order?.orderInfo?.customer_mtm
)的“2级”属性。如果您只访问1级(like order.orderInfo
),它将起作用。
这是有道理的,因为我们假设您在javascript var a = {}; a.something works
中运行此代码,但由于a.something1.something2
为something1
而无法执行undefined
。
现在回到你的问题,我的建议是创建一个子组件并将order
对象传递给它,或者你可以在构造函数中创建一个空的order
对象。
像
这样的东西var order = {};
order.orderInfo = {};
希望它有意义。