Làm cách nào để đặt giá trị mặc định cho các thuộc tính thành phần Angular 2?


101

Khi viết các thành phần Angular 2.0, làm cách nào để đặt giá trị mặc định cho các thuộc tính?

Ví dụ - tôi muốn đặt foothành 'bar'theo mặc định, nhưng ràng buộc có thể giải quyết ngay lập tức thành 'baz'. Điều này diễn ra như thế nào trong các móc vòng đời?

@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);
    }
}

Với các mẫu sau, đây là những gì tôi mong đợi các giá trị sẽ là. Tôi có lầm không?

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

Đã đăng nhập vào bảng điều khiển:

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

Đã đăng nhập vào bảng điều khiển:

'bar'
undefined
undefined

Điều gì xảy ra khi bạn thử nó?
JB Nizet

1
@BryanRayner, cách mà bảng điều khiển hiện đang được in là chính xác.. vấn đề mà bạn gặp phải là gì?
Pankaj Parkar

6
Tôi hiện không phải đối mặt với vấn đề gì, chỉ đang tìm cách làm rõ về hành vi dự định. Khi tôi không tìm thấy câu trả lời cho sự tò mò của mình, tôi quyết định sẽ hỏi câu hỏi này trong trường hợp những người khác có cùng mong muốn được rõ ràng.
Bryan Rayner,

Trong ví dụ của bạn, bạn đang thiếu ngoặc trên @Input ()
kitimenpolku

Câu trả lời:


142

Đó là chủ đề thú vị. Bạn có thể thử với hai móc vòng đời để tìm ra cách hoạt động của nó: ngOnChangesngOnInit.

Về cơ bản khi bạn đặt giá trị mặc định thành giá trị Inputđó có nghĩa là nó sẽ chỉ được sử dụng trong trường hợp không có giá trị nào đến trên thành phần đó. Và phần thú vị là nó sẽ được thay đổi trước khi thành phần được khởi tạo.

Giả sử chúng ta có các thành phần như vậy với hai móc vòng đời và một thuộc tính đến từ 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);
  }

}

Tình huống 1

Thành phần được bao gồm trong html mà không có propertygiá trị xác định

Kết quả là chúng ta sẽ thấy trong bảng điều khiển: Init default

Điều đó có nghĩa là onChangeđã không được kích hoạt. Init đã được kích hoạt và propertygiá trị defaultnhư mong đợi.

Tình huống 2

Thành phần bao gồm trong html với thuộc tính setted <cmp [property]="'new value'"></cmp>

Kết quả là chúng ta sẽ thấy trong bảng điều khiển:

Changed new value Object {}

Init new value

Và điều này là thú vị. Đầu tiên là onChangehook được kích hoạt , được đặt propertythành new value, và giá trị trước đó là đối tượng trống ! Và chỉ sau khi onInithook đó được kích hoạt với giá trị mới là property.


8
Có bất kỳ liên kết nào đến các tài liệu chính thức cho hành vi này không? Sẽ rất tốt nếu bạn hiểu logic và lập luận đằng sau điều này, cũng có thể theo dõi hành vi của mỗi phiên bản.
Bryan Rayner

Tôi đã không nhìn thấy thông tin như vậy, tất cả ở trên là điều tra của riêng tôi. Tôi nghĩ bạn có thể tìm thấy nhiều câu trả lời hơn nếu bạn đọc các tệp js đã biên dịch
Mikki

1
Tôi đang tìm kiếm tài liệu về các @Inputgiá trị mặc định. @slicepan có liên kết đến các tài liệu cho vòng đời thành phần, nhưng tôi không thấy giá trị mặc định được sử dụng trong tài liệu.
nycynik

@nycynik chỉ cần sử dụng điều này cho các giá trị mặc định:@Input() someProperty = 'someValue';
magikMaker 13/03/18

1
Bạn là phao cứu sinh. Điều này làm đau đầu của tôi, trong khi đã nâng cấp từ ứng dụng AngularJS để 7.x góc
Andris

9

Đây là giải pháp tốt nhất cho điều này. (ANGULAR Tất cả các phiên bản)

Giải pháp khắc phục : Để đặt giá trị mặc định cho biến @Input . Nếu không có giá trị nào được truyền cho biến đầu vào đó thì Nó sẽ nhận giá trị mặc định .

Tôi đã cung cấp giải pháp cho loại câu hỏi tương tự. Bạn có thể tìm thấy giải pháp đầy đủ từ đây

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);
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.