1
votes

Comment détecter le changement d'objet complexe dans Angular?

Je travaille sur un projet angulaire. J'ai donc un objet de style complext et je le lie à mon composant angulaire.

app.component.ts

@Component({
    selector: 'my-component',
    template: `<ng-content></ng-content>`,
})
export class MyComponent implements AfterContentInit {
    style: any;
    thirdPartyObject: Style;

    ngOnInit(): void {
        this.style = new Style({
            radius: style.radius,
            fill: new Fill({ color: style.fill.color }),
            stroke: new Stroke({ color: style.stroke.color, width: style.stroke.width })
        });
    }

    ngAfterContentInit(): void {
        thirdPartyObject.setStyle(function(){
            return this style;          
        })
    }
}

app .component.html

Et my-component récupère l'objet et l'utilise avec un objet tiers.

my. component.ts

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

    style:any;

    ngOnInit() {
        this.style = { 
            radius:15, 
            fill: { 
                color: "red" 
            }, 
            stroke: { 
                color: "blue", 
                width: 3 
            } 
        }
    }
}

Je crée l'objet Style tiers en utilisant un objet style provenant de app.component. Et thirdPartyObject a une fonction nommée setStyle () pour obtenir l'objet de style.

Donc, quand je change la propriété de style dans app.component, comment puis-je mettre à jour mon composant? Cette liaison est différente.


4 commentaires

Vous pouvez utiliser EventEmitter.


comment actualiser mon-composant , que faut-il mettre à jour dans MyComponent ..?


@ ganesh045 La liaison de propriété angulaire déclenche le sous-composant. Lorsque je change un sous-composant lié à une propriété, il change immédiatement. Mais dans cette position, j'ai un objet complexe. Alors, comment puis-je le faire?


cette position j'ai un objet complexe il ne s'agit pas d'un objet complexe ou d'un objet simple. ce dont vous avez besoin de mise à jour, est-ce une variable de composant enfant du composant parent ou une variable de composant parent du composant enfant ... peut-être que je ne comprends pas correctement vos besoins. pouvez-vous l'élaborer une fois ...;)


3 Réponses :


0
votes

Vous pouvez utiliser le ChangeDetectorRef d'Angular pour détecter manuellement les modifications et tigger un rendu

@Component({
    selector: 'my-component',
    template: `<ng-content></ng-content>`,
})
export class MyComponent implements AfterContentInit {
    style: any;
    thirdPartyObject: Style;

    constructor(private ref: ChangeDetectorRef) { }

    ngOnInit(): void {
        this.style = new Style({
            radius: style.radius,
            fill: new Fill({ color: style.fill.color }),
            stroke: new Stroke({ color: style.stroke.color, width: style.stroke.width })
        });
    }

    ngAfterContentInit(): void {
        this.setStylesToThirdPartyObject();
    }

    setStylesToThirdPartyObject(): void {
        thirdPartyObject.setStyle(function(){
            return this style;          
        });
        this.ref.detectChanges();
    }
}

En savoir plus sur CDR sur https://angular.io/api/core/ChangeDetectorRef


0 commentaires

0
votes

voici un exemple complet de détection de changement en angulaire:

<div class="mat-elevation-z8">
    <form  **(change)="onChange($event,r.value)**">  
        <fieldset class="material">
          <label>Radius</label>
          <hr>
          <input #r type="number" placeholder={{radius}} autocomplete="on" value = 5 required> 
        </fieldset>
        <ng-container *ngIf="!render">
           <app-calc-component value={{r.value}} selCalc='circulararea'></app-calc-component>
      </ng-container>
      </form>
 </div>

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { CalcComponent } from '../calc-component';

@Component({
  selector: 'app-circular-area',
  templateUrl: './circular-area.component.html',
  styleUrls: ['./circular-area.component.scss']
})
export class CircularAreaComponent implements OnInit {
  public render: Boolean;
  public radius: number;
  public r: number;
  constructor(private cdRef: ChangeDetectorRef) { }

  **onChange**(event: any, r: number) {
    console.log(r);
    this.r = Number(r);
    this.render = true;
    this.cdRef.detectChanges();
    this.render = false;
  }

  ngOnInit() {
    this.render = false;
  }
}

La méthode onChange déclenche le changeDetection. Voir aussi sur mon git dans Calculate-component


0 commentaires

0
votes

Je suggère de transmettre le style à votre composant enfant en utilisant @Input code> class decorator, de sorte que angular puisse garder une trace de l'objet style et restituer votre composant enfant lorsqu'il détecte un changement.

Dans votre app.component.html:

changeStyleStroke(){
   let newStroke = {
      stroke: { 
        color: "red", 
        width: 3 
      } 
   };

   //Update style this way will trigger change detection that detect changes and re-render your component

   this.style = {...this.style, ...stroke};
 }

Dans le fichier ts de votre composant enfant, appliquez setStyle dans ngOnInit et ngOnChanges:

 @Input() style: any;
 ngOnInit() {
   thirdPartyObject.setStyle(function() { return this.style });
 }
 ngOnChanges() {
   thirdPartyObject.setStyle(function() { return this.style });   
 } 

Et puisque style est un objet, le suivi angulaire est une référence, ce n'est pas sa propriété, vous devez donc changer le style en créant un nouvel objet (similaire à la modification de l'état de react):

Dans le fichier ts de votre composant d'application:

<your-component [style]="style"></your-component>


0 commentaires