2017-09-29 2 views
1

J'ai un composant parent, 'EmployeeComponent' qui affiche une liste d'employés. Et j'ai un composant enfant, 'EmployeeDetailComponent' qui affiche les détails d'un employé sélectionné (nom, email, etc.).Pourquoi la copie manuelle des attributs d'un objet met-elle à jour la vue alors que Object.assign() ne le fait pas?

L'employé sélectionné est passé du parent à l'enfant en utilisant @input comme ceci:

@Input() employee: Employee; // This line goes in the child component 

Le composant enfant permet également de modifier les informations. Une fois modifiée, le nouvel objet employé est ensuite transmis au composant parent en utilisant un émetteur même comme ceci:

Dans le composant enfant:

@Output() onSaved = new EvenEmitter<Employee>(); 
onSubmit(){ 
    this.onSaved.emit(this.employee); 
} 

Et dans le composant parent:

onSaved(employee: Employee){ 

    // The line below doesn't affect employee's details in the view 
    this.selectedEmployee = Object.assign({}, employee); 

    // However, old values are successfully replaced by new ones 
    console.log(this.selectedEmployee); 

    //And the line below changes successfully the employee's details in the view 
    this.employee.name = employee.name; 

} 

Ma question est donc, puisque dans les deux sens, les détails de l'employé sont changés, pourquoi la deuxième façon affecte-t-elle l'information dans la vue et pas la première?

Répondre

1

Object.assign() renvoie la même instance d'objet. La détection de changement angulaire vérifie uniquement l'identité de l'objet, mais pas le contenu des objets lorsqu'il compare l'ancienne et la nouvelle valeur.

Si vous avez un autre objet, la détection de changement angulaire le considère comme un changement, même si l'objet contient les mêmes propriétés avec les mêmes valeurs. Cela provoque le rendu de la vue.

+0

Oh d'accord, alors dans ce cas, comment dois-je faire pour remplacer les anciennes valeurs par les nouvelles? Je dois éviter de le faire manuellement et un par un ... – iMadz

+1

Lorsque vous utilisez 'this.selectedEmployee = Object.assign ({}, employee);' où target (premier paramètre) est un nouvel objet, alors le résultat devrait être un nouvel objet. Vous créez essentiellement un clone de cette façon, puis la détection de changement reconnaîtra le changement. Si vous utilisez 'this.selectedEmployee = Object.assign (oldEmpl, newEmpl);', alors 'oldEmpl' reste le même objet et seul son contenu est modifié. –