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

Posted

技术标签:

【中文标题】Angular - 如何为可选输入属性设置默认值【英文标题】:Angular - How to set default values for optional input properties 【发布时间】:2019-09-24 03:03:53 【问题描述】:

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

目前我有这样的事情:

export class FooComponent implements OnInit 
  @Input() foo = 'foo';
  @Input() bar = 0;
  @Input() baz?: string;

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

或者,您可以使用? 标记此属性是可选的,但您不能声明其默认值。 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,你发送&lt;app-fool [mynumber]='Hello word'/&gt; 【参考方案1】:

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

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

例子:

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

export interface car 
  isCar?: boolean;
  wheels?: number;
  engine?: string;
  engineType?: string;

您创建了一个名为 app-car 的组件,您需要在其中使用 @input 角度装饰器 传递汽车的属性。但是您希望 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);
  

更详细的文章请参考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 - 如何为可选输入属性设置默认值的主要内容,如果未能解决你的问题,请参考以下文章

代码优先迁移:如何为新属性设置默认值?

如何为 Laravel / Eloquent 模型设置默认属性值?

如何为注释类型编码可选的默认注释值

C#:如何为部分类中的属性设置默认值?

更新CoreData模型版本时如何为实体的新属性设置默认值

如何为 kendo ui 下拉菜单设置默认值?