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

时间:2016-03-17 21:23:43

标签: angular

编写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>

Logged to console: 
'baz'
'bar'
'baz'

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

Logged to console: 
'bar'
undefined
undefined

2 个答案:

答案 0 :(得分:68)

这是一个有趣的主题。 您可以使用两个生命周期钩子来弄清楚它是如何工作的: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未被触发。触发了Init,property值为default,符合预期。

情况2

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

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

Changed new value Object {}

Init new value

这个很有意思。首先是触发onChange挂钩,将property设置为new value,之前的值为空对象!只有在用onInit的新值触发property挂钩之后。

答案 1 :(得分:9)

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

寻址解决方案:要 设置@Input变量的默认值 。如果 没有值传递到该输入变量,则它将采用默认值

我已为此类类似问题提供了解决方案。您可以从here

中找到完整的解决方案
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);
  }
}