Как установить значения по умолчанию для свойств компонента Angular 2?

102

Как при написании компонентов 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
6
В настоящее время я не сталкиваюсь с проблемой, просто ищу разъяснений относительно предполагаемого поведения. Когда я не нашел ответа на свое любопытство, я решил, что задам вопрос, если у других будет такое же желание ясности.
Bryan Rayner
В вашем примере вам не хватает круглых скобок в @Input ()
kitimenpolku

Ответы:

142

Это интересная тема. Вы можете поиграть с двумя хуками жизненного цикла, чтобы понять, как это работает: ngOnChangesи ngOnInit.

В основном, когда вы устанавливаете значение по умолчанию 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хук, который установил propertyзначение new value, а предыдущее значение было пустым объектом ! И только после этого onInitсработал хук с новым значением property.

Микки
источник
8
Есть ли ссылки на официальную документацию по этому поводу? Было бы хорошо понять логику и рассуждения, стоящие за этим, а также иметь возможность отслеживать, каково поведение для каждой версии.
Брайан Рейнер,
Я не видел такой информации, все это мое собственное расследование. Думаю, вы сможете найти больше ответов, если прочитаете скомпилированные js-файлы
Mikki
1
Я искал документацию о @Inputзначениях по умолчанию. @slicepan имеет ссылку на документацию по жизненному циклу компонента, но я не видел значения по умолчанию, используемого в документации.
nycynik
@nycynik просто используйте это для значений по умолчанию:@Input() someProperty = 'someValue';
magikMaker
1
Вы спасатель. У меня разболелась голова во время обновления приложения AngularJS до Angular 7.x
Андрис
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);
  }
}
Парт Девлопер
источник