带有空对象的Angular2-[(ngModel)]

带有空对象的Angular2-[(ngModel)],angular,Angular,我有一个包含各种输入、选项和选择的表单。表格分为多个部分。例如: order.orderInfo.customerName order.orderInfo.address order.model.size order.model.options order.trims.selectedTrims 如果Order={}那么它会崩溃,并出现未定义的错误。我的第一个想法是使用elvis运算符,但Angular不允许在作业中使用它。到目前为止,我发现的唯一“解决方案”是根本不使用[(ngModel)]

我有一个包含各种输入、选项和选择的表单。表格分为多个部分。例如:

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)
语法,或者我是否在这里遇到了概念上的错误?

它崩溃的原因是您正在访问
订单
对象(
订单?.orderInfo?.customer\u mtm
)的“2级”属性。如果您只访问一个级别(
,如order.orderInfo
),它将起作用

这是有意义的,因为假设您在javascript
var a={}中运行此代码;a、 有些东西可以工作,但你不能做,因为
something1
未定义的

现在回到您的问题,我的建议是要么创建一个子组件并将您的
order
对象传递给它,要么您可以在构造函数中创建一个空的
order
对象

差不多

var order = {};
order.orderInfo = {};

希望这是有意义的。

也许有一些方法可以解决这个问题,但下面是我如何看待它的

在控制器中,创建一个基础对象作为常量。对你来说,这将是:

const ORDER_BASE = { someprop : 'somedefaultval', ... }
该基地应满足所有要求,否则您将使用elvis操作员。在构造函数中为模型设置值时(不是ngInit,否则会出现未定义的错误),可以执行以下操作:

(这将创建对象的副本,因此您不会将基准参照用作模型)

或者,您可以使用factory ish功能:

this.order = makeFreshOrder ( );

makeFreshOrder ( ) {
     return Object.assign ( {}, ORDER_BASE );
}
这可以让你摆脱elvis操作符的困扰,不用担心init上有什么属性,等等

我尽量将标记中的逻辑控制在最低限度,在我工作过的几个地方,这是最佳实践。除了在带有三元表达式的标记中进行真正简单的决策/检查/验证之外,不要做任何事情(这会变得很麻烦),在控制器中进行

(请注意,基本对象可以是“Order”类的新实例……键入此类内容可能会很有用)

事实上,有人在标记中告诉我,“如果你在使用elvis操作符,你就是在偷懒。”我对此不太清楚,但我确实理解这一点

this.order = makeFreshOrder ( );

makeFreshOrder ( ) {
     return Object.assign ( {}, ORDER_BASE );
}