Angular 10/Typescript: Vad är skillnaden mellan hur samma egenskap hos ett objekt tilldelas


Jag har ett objekt Person som skickas vidare från en föräldrakomponent som visas nedan. Namnet initialiseras till en tom sträng när egenskapen deklareras innan ngOnInit(). Egenskapen används för att sätta en boolean i en annan komponent. Även om föräldrakomponenten har värdet name=John i föräldrakomponenten, raderar scenario 1 det värdet till en tom sträng och påverkar därmed booleanen. Scenario 2 ändrar inte värdet av name=John. Vad är skillnaden mellan de två tilldelningarna i scenario 1 och 2? Och varför raderar scenario 1 det ursprungliga värdet i föräldrakomponenten?

export interface IPerson {
 name?: string;
}

// In a child component:
@Input() person: IPerson = { name: '' }

// scenario 1:
ngOnInit(): void {

  this.person.name = '';

}

// scenario 2:
ngOnInit(): void {
this.person = { name: '' }

}

Svar #1

Jag tror att detta blir tydligare om du använder ett distinkt värde istället för en tom sträng. Säg att vi har samma upplägg:

export interface IPerson {
    name?: string
}

@Component({ 
  selector: 'app-parent', 
  template: `
    <p>Parent value: {{person.name}}</p>
    <app-child [person]="person"></app-child>`
})
export class ParentComponent {
  person: IPerson = { name: 'John' };
}

@Component({
  selector: 'app-child',
  template: `<p>Child value: {{person.name}}</p>`
})
export class ChildComponent implements OnInit {
  @Input() person: IPerson = { name: '' };

  ngOnInit() {
    // Scenario 1:
    this.person.name = 'Felicity';
    // Scenario 2:
    this.person = { name: 'Norah' };
  }
}

När du renderar komponenten som är förälder kommer du att se något liknande detta:

Parent value: Felicity
Child value: Norah

Detta beror på att i scenario 1 har vi ändrat name-fältet på förälderns objekt. Det skickades "som referens", om man så vill, så ändringar i fältet har förändrat vad föräldern vet.

Scenario 2 har glömt bort objektet från föräldern och ersatt det med ett nytt objekt som bara barnet känner till. Därför ser vi två olika namn; ett i föräldern och ett i barnet.

Lek runt med det med hjälp av denna StackBlitz.


I ditt fall skriver scenario 1 över "John" eftersom du ändrar det faktiska objektet som skickats från föräldern. Scenario 2 skriver inte över "John" eftersom du arbetar med ett nytt objekt, inte det som skickats från föräldern.