如何设置Angular 2组件属性的默认值?


101

编写Angular 2.0组件时,如何设置属性的默认值?

例如-我想默认设置foo'bar',但是绑定可能会立即解析为'baz'。如何在生命周期挂钩中发挥作用?

@Component({  
    selector: 'foo-component'
})
export class FooComponent {
    @Input()
    foo: string = 'bar';

    @Input()
    zalgo: string;

    ngOnChanges(changes){
          console.log(this.foo);
          console.log(changes.foo ? changes.foo.previousValue : undefined);
          console.log(changes.foo ? changes.foo.currentValue : undefined);
    }
}

给定以下模板,这就是我期望的值。我错了吗?

<foo-component [foo] = 'baz'></foo-component>

登录到控制台:

'baz'
'bar'
'baz'
<foo-component [zalgo] = 'released'></foo-component>

登录到控制台:

'bar'
undefined
undefined

尝试时会发生什么?
JB Nizet

1
@BryanRayner当前控制台的打印方式是正确的..您面临的问题是什么?
Pankaj Parkar,2016年

6
我目前没有遇到任何问题,只是在澄清预期的行为。当我没有找到好奇心的答案时,我决定我会问这个问题,以防其他人也有同样的要求。
Bryan Rayner

在您的示例中,您缺少@Input()上的括号
kitimenpolku,2016年

Answers:


142

那是有趣的话题。您可以使用两个生命周期挂钩来弄清楚它是如何工作的:ngOnChangesngOnInit

基本上,将默认值设置Input为该值意味着仅在该组件上没有值的情况下才使用它。有趣的是,它将在组件初始化之前进行更改。

假设我们有这样的组件,它们带有两个生命周期挂钩和一个来自的属性input

@Component({
  selector: 'cmp',
})
export class Login implements OnChanges, OnInit {
  @Input() property: string = 'default';

  ngOnChanges(changes) {
    console.log('Changed', changes.property.currentValue, changes.property.previousValue);
  }

  ngOnInit() {
    console.log('Init', this.property);
  }

}

情况1

html中包含的组件,未定义property

结果,我们将在控制台中看到: Init default

那意味着onChange没有被触发。初始化被触发并且property值是default预期的。

情况2

HTML中包含的具有设置属性的组件 <cmp [property]="'new value'"></cmp>

结果,我们将在控制台中看到:

Changed new value Object {}

Init new value

这个很有趣。首先触发onChange钩子,将其设置propertynew value,而先前的值是空对象!而且只有在该onInit钩子被触发后才带有新值property


8
是否有此行为的官方文档链接?最好了解其背后的逻辑和推理,也能够跟踪每个版本的行为。
布莱恩·雷纳

我没有看到这样的信息,以上都是我自己的调查。我认为,如果您将阅读已编译的js文件,则可以找到更多答案
Mikki 2016年

1
我正在寻找@Input具有默认值的文档。@slicepan有一个指向组件生命周期文档的链接,但是我没有在文档中看到默认值。
nycynik

@nycynik只需将其用作默认值即可:@Input() someProperty = 'someValue';
magikMaker

1
你是救星。当我从AngularJS应用升级到Angular 7.x时,这让我很头疼
Andris

9

这是对此的最佳解决方案。(所有版本)

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

我已经为这种类似的问题提供了解决方案。您可以从这里找到完整的解决方案

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);
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.