Angular - 如何为可选输入属性设置默认值
Posted
技术标签:
【中文标题】Angular - 如何为可选输入属性设置默认值【英文标题】:Angular - How to set default values for optional input properties 【发布时间】:2019-09-24 03:03:53 【问题描述】:我想知道在 Angular 组件中为可选属性设置默认值的“Angular/Typescript 方式”是什么?当传递给可选属性的值为null
或undefined
时,我遇到了麻烦。
目前我有这样的事情:
export class FooComponent implements OnInit
@Input() foo = 'foo';
@Input() bar = 0;
@Input() baz?: string;
如果您声明默认值,则不必指定类型,因为它是分配值的类型,并且默认情况下属性是可选的。这是bar
和foo
属性的情况。
或者,您可以使用?
标记此属性是可选的,但您不能声明其默认值。 baz
属性就是这种情况。
现在让我们看看当您将不同的值传递给这些属性时会发生什么。
<app-foo-component
[foo]
[bar]="null"
[baz]="undefined"
>
</app-foo-component>
如果我在控制台记录这些属性,这就是我得到的:
foo
将是正确的'foo'
bar
将是 null
baz
将是 undefined
当传递的值为空/未定义时,是否有一种优雅的方法来设置默认值,或者我是否需要像这样检查 OnInit?
OnInit()
this.bar = this.bar || 0;
感觉好像有一些方法可以做到这一点。对我来说,可选属性意味着值可能会丢失、null 或未设置,但是当我想设置默认值时,它仅在属性丢失或为空时才有效。在这些情况下,它仍然将 value 设置为 null 或 undefined,这似乎令人困惑。
【问题讨论】:
确实可以声明类型,但请记住 typescript 转换为 javascript 并且变量获取您发送的值的类型。例如你有一个@Input() mynumber:number
,你发送<app-fool [mynumber]='Hello word'/>
【参考方案1】:
这是 PROPER 最佳 解决方案。 (角度 7,8, 9)
解决方案:为@Input 变量设置一个默认值。如果没有值传递给该输入变量,那么它将采用默认值。
例子:
我有一个名为 car 的对象接口:
export interface car
isCar?: boolean;
wheels?: number;
engine?: string;
engineType?: string;
您创建了一个名为 app-car 的组件,您需要在其中使用 @input 角度装饰器 传递汽车的属性。但是您希望 isCar 和 Wheels 属性必须具有默认值(即..isCar: true,wheels: 4)
您可以按照以下代码为该对象设置默认值:
export class CarComponent implements OnInit
private _defaultCar: car =
// default isCar is true
isCar: true,
// default wheels will be 4
wheels: 4
;
@Input() newCar: car = ;
constructor()
ngOnInit(): void
// this will concate both the objects and the object declared later (ie.. ...this.newCar )
// will overwrite the default value. ONLY AND ONLY IF DEFAULT VALUE IS PRESENT
this.newCar = ...this._defaultCar, ...this.newCar ;
// console.log(this.newCar);
更详细的文章请参考this。
从这里参考Destructuring assignment
【讨论】:
您的解决方案仅在“汽车”接口具有所有可选属性时才有效,否则,您不能将@Input 的默认值设置为空对象。 您好@gesiud,我已经测试了代码并且当newCar
是空对象时工作正常。如果您有任何问题,也可以分享您的 stackBlitz 链接,我很乐意为您提供帮助。
抱歉,我错过了您帖子中的接口声明,但无论如何@Input() newCar: car = ;
仅在所有接口属性都是可选的情况下才有效,并且在许多情况下这不是所需的模式,相反,您可以省略赋值和像这样声明:@Input() newCar: car
,
如果在 ngOnInit 之后 @Input 的值发生了变化,默认可能无法正确应用,我们可能仍然需要 setter 方法或 ngOnChanges 钩子。我的论点正确吗?
@JieWang 我不确定。看起来你的论点是合乎逻辑的。但需要测试后再确认。【参考方案2】:
当有一些嵌套的子组件时,我遇到了同样的问题。
最后这对我有用:
@Input()
public foo;
get fooWithDefault()
return this.foo ?? 'any default value';
然后我在模板中使用fooWithDefault
属性而不是foo
。
【讨论】:
它就像一个魅力。谢谢【参考方案3】:您可以将bar
定义为getter/setter 属性,并确保在必要时在setter 中应用默认值:
private _bar = 0;
@Input() get bar()
return this._bar;
set bar(value)
this._bar = value || 0;
请参阅this stackblitz 以获取演示。
【讨论】:
我几乎喜欢这个。我会改变二传手中一个至关重要的东西。我会使用检查 null 而不是||
: this._bar = value != null ? value : 'default';
@A.Chiesa Nullish Coalescing Operator 会更合适。见:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
@GarethAS 是的,如果浏览器兼容性不是问题的话。这是一项仅在 2020 年发布的浏览器中本机支持的功能,并且它的工作原理与三元一样完全。当我评论该功能时,该功能已经发布了 5 天 :)以上是关于Angular - 如何为可选输入属性设置默认值的主要内容,如果未能解决你的问题,请参考以下文章