Angular - 如何为可选输入属性设置默认值

All*_*lwe 6 typescript angular-components angular

我想知道在 Angular 组件中为可选属性设置默认值的“Angular/Typescript 方式”是什么?当传递给可选属性的值是nullor时,我遇到了麻烦undefined

目前我有这样的事情:

export class FooComponent implements OnInit {
  @Input() foo = 'foo';
  @Input() bar = 0;
  @Input() baz?: string;
}
Run Code Online (Sandbox Code Playgroud)

如果声明默认值,则不必指定类型,因为它是指定值的类型,默认情况下属性是可选的。barfoo属性就是这种情况。

或者,您可以使用?标记此属性是可选的,但不能声明其默认值。这就是baz财产的情况。

现在让我们看看当您将不同的值传递给这些属性时会发生什么。

<app-foo-component
  [foo]
  [bar]="null"
  [baz]="undefined"
>
</app-foo-component>
Run Code Online (Sandbox Code Playgroud)

如果我控制台记录这些属性,这就是我得到的:

foo 会正确 'foo'

bar 将会 null

baz 将会 undefined

当传递的值为空/未定义时,是否有一种优雅的方法也可以设置默认值,或者我是否需要像这样在 OnInit 中进行一些检查?

OnInit() {
  this.bar = this.bar || 0;
}
Run Code Online (Sandbox Code Playgroud)

感觉有一些方法可以做到这一点。对我来说,可选属性意味着值可能丢失、为空或未设置,但是当我想设置默认值时,它仅在属性丢失或为空时才有效。在这些情况下,它仍然将 value 设置为 null 或 undefined,这似乎令人困惑。

Con*_*Fan 6

您可以定义bar为 getter/setter 属性,并确保在必要时在 setter 中应用默认值:

private _bar = 0;

@Input() get bar() {
  return this._bar;
}
set bar(value) {
  this._bar = value || 0;
}
Run Code Online (Sandbox Code Playgroud)

请参阅此 stackblitz的演示。


Par*_*per 5

这是正确的 最佳 解决方案(角度 7,8, 9)

解决方案为@Input 变量设置默认值。如果没有值传递给该输入变量,则它将采用默认值。

例子:

我有一个名为 car 的对象接口:

export interface car {
  isCar?: boolean;
  wheels?: number;
  engine?: string;
  engineType?: string;
}
Run Code Online (Sandbox Code Playgroud)

您创建了一个名为app-car的组件,您需要在其中使用angular 的 @input 装饰器传递 car 的属性。但是你希望isCarWheels属性必须有一个默认值(即.. 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

有关更详细的文章,请参阅

从这里参考解构赋值

  • 抱歉,我在您的帖子中错过了接口声明,但无论如何 `@Input() newCar: car = {};` 仅当所有接口属性都是可选的时才有效,并且在许多情况下这不是所需的模式,相反,您可以省略赋值并进行如下声明:`@Input() newCar: car`, (2认同)