วิธีการตั้งค่าเริ่มต้นสำหรับคุณสมบัติส่วนประกอบ Angular 2


105

เมื่อเขียนคอมโพเนนต์ 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

7
ขณะนี้ฉันไม่ได้ประสบปัญหาเพียงแค่ขอคำชี้แจงเกี่ยวกับพฤติกรรมที่ตั้งใจไว้ เมื่อฉันไม่พบคำตอบสำหรับความอยากรู้อยากเห็นของฉันฉันตัดสินใจว่าจะถามคำถามในกรณีที่คนอื่นต้องการความชัดเจนเช่นเดียวกัน
Bryan Rayner

ในตัวอย่างของคุณคุณไม่มีวงเล็บใน @Input ()
kitimenpolku

คำตอบ:


148

นั่นคือเรื่องที่น่าสนใจ คุณสามารถเล่นรอบสองตะขอวงจรที่จะคิดออกวิธีการทำงาน: และ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 พร้อมคุณสมบัติ setted <cmp [property]="'new value'"></cmp>

ดังนั้นเราจะเห็นในคอนโซล:

Changed new value Object {}

Init new value

และอันนี้น่าสนใจ ประการแรกถูกเรียกonChangeเบ็ดซึ่ง setted propertyไปnew valueและความคุ้มค่าก่อนหน้านี้เป็นวัตถุที่ว่างเปล่า ! และหลังจากนั้นonInithook ก็ถูกเรียกด้วยค่าใหม่ของproperty.


10
มีลิงก์ไปยังเอกสารอย่างเป็นทางการสำหรับพฤติกรรมนี้หรือไม่ จะเป็นการดีที่จะเข้าใจตรรกะและเหตุผลที่อยู่เบื้องหลังสิ่งนี้และยังสามารถติดตามพฤติกรรมของแต่ละเวอร์ชัน
Bryan Rayner

ฉันไม่เห็นข้อมูลดังกล่าวข้างต้นทั้งหมดเป็นการสอบสวนของฉันเอง ฉันคิดว่าคุณสามารถหาคำตอบเพิ่มเติมได้หากคุณจะอ่านไฟล์ js ที่คอมไพล์แล้ว
Mikki

1
ฉันกำลังมองหาเอกสารเกี่ยวกับการ@Inputมีค่าเริ่มต้น @slicepan มีลิงก์ไปยังเอกสารสำหรับวงจรการใช้งานส่วนประกอบ แต่ฉันไม่เห็นค่าเริ่มต้นที่ใช้ในเอกสารประกอบ
nycynik

@nycynik เพียงใช้สิ่งนี้สำหรับค่าเริ่มต้น:@Input() someProperty = 'someValue';
magikMaker

1
คุณเป็นผู้ช่วยชีวิต สิ่งนี้ทำให้หัวของฉันเจ็บขณะที่อัปเกรดจากแอป AngularJS เป็น Angular 7.x
Andris

10

นี่คือทางออกที่ดีที่สุดสำหรับสิ่งนี้ (ANGULAR ทุกรุ่น)

วิธีการแก้ปัญหาที่อยู่ : ในการตั้งค่าเริ่มต้นสำหรับตัวแปร @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);
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.