1
votes

Le composant d'élément angulaire ne se met pas à jour lorsque j'ajoute un objet à partir d'une propriété

J'ai un composant d'élément angulaire (avec Angular 8) qui a 2 accessoires. Quand j'essaye de pousser quelque chose dans le tableau, le Shadow-Root ne le rend pas (le compteur oui à la place). Comment puis-je forcer le rendu lorsque je pousse un objet dans le composant?

Merci

Ceci est la classe Component

<div style="display: flex;justify-content: center;flex-direction: column">
    <h1>Counter component</h1>
    <h4>Count ---> {{counter}}</h4>
    <button (click)="add()">Increase</button>
    <button (click)="reduce()">Decrease</button>
</div>

<h3>
Images {{images.length}}
</h3>

AppModule

import { BrowserModule, platformBrowser } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';

import { CounterComponent } from './counter/counter.component';
import { createCustomElement } from '@angular/elements';

@NgModule({
  declarations: [
    CounterComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  entryComponents: [CounterComponent]
})
export class AppModule {

  constructor(private injector: Injector) {

  }

  ngDoBootstrap( ) {
    const el = createCustomElement(CounterComponent, {injector: this.injector});
    customElements.define('count-component', el);
  }
 }

Voici le modèle de composant

export class CounterComponent implements OnInit {

  @Input()
  counter: number;

  @Input()
  images: Array<any>;

  constructor(private cdr: ChangeDetectorRef) { }

  ngOnInit() {
    this.counter = 0;
    this.images = [];
  }

  add() {
    this.counter++;
  }

  reduce() {
    this.counter--;
  }

  @Input()
  addImage() {
    this.images.push({ ciccio: 'piccio'}); //no rerender
    this.cdr.detectChanges(); // Error cdr is null
  }
}


6 commentaires

ont créé une démo ( stackblitz.com/edit/angular-vrcsj4 ) basée sur votre code. L'interface utilisateur semble rendre la longueur du tableau modifiée lors de l'ajout de nouveaux éléments au tableau. Pouvez-vous s'il vous plaît expliquer un peu plus le problème auquel vous êtes confronté.


@SiddhantPatra votre démo n'est pas pertinente, il utilise des éléments angulaires ( @ angular / elements ) qui fonctionnent un peu différemment de Angular "normal".


@Input () set counter (val) {console.log (val)}


ajoutez votre code à stackblitz, afin que tout le monde puisse comprendre


next.plnkr.co/edit/nt5YkmCpOgm2UJcR


Avez-vous essayé de changer la matrice réelle? C'est à dire. this.images = [... this.images, {ciccio: 'piccio'}];


3 Réponses :


0
votes
  @Input()
  addImage() {
     this.ngZone.run(() => {
        this.images.push({ ciccio: 'piccio'}); //no rerender
     });
  }
Can you try injecting NgZone from @angular/core and run inside it?

2 commentaires

les éléments angulaires n'injectent pas de ngZone dans le composant


désolé, je n'ai pas compris. Êtes-vous en train de dire que nous ne pouvons pas injecter ngZone dans le composant?



0
votes

Selon "Angular Elements Overview" dans la documentation d'Angular:

Nous travaillons sur des éléments personnalisés qui peuvent être utilisés par des applications Web construites sur d'autres frameworks. Une version minimale et autonome du framework Angular sera injectée en tant que service pour prendre en charge la fonctionnalité de détection des changements et de liaison de données du composant. Pour en savoir plus sur la direction du développement, regardez cette présentation vidéo .

Comme indiqué dans 8:28 dans la présentation vidéo ci-dessus , l'injection de dépendances fonctionne pour les éléments personnalisés dans Angular Elements. Par conséquent, injectez ChangeDetectorRef dans votre élément personnalisé et appelez detectChanges () lors de la mutation de votre tableau images , comme ceci:

export class CounterComponent /* ... */ {
    constructor(private cdr: ChangeDetectorRef) { }   
    /* ... */
    addImage() {
        this.images.push({ ciccio: 'piccio'});
        this.cdr.detectChanges(); // change detection will detect the change in `images` and render
    }
}


2 commentaires

Je reiceve cette erreur -> Impossible de lire la propriété 'detectChanges' de undefined


@Bonfry On dirait que ChangeDetectorRef n'a pas été réellement injecté. Avez-vous transmis une instance Injector comme option lorsque vous avez appelé createCustomElement ( ) pour créer votre élément CounterComponent personnalisé?



0
votes

Essayez ceci, qui changera réellement la valeur de la propriété images sur votre composant, lui permettant de voir le changement:

  @Input()
  addImage() {
    this.images = [...this.images, { ciccio: 'piccio'}]; // should render
  }

Plunk: ici


1 commentaires

Cela fonctionne grâce à Angular détectant le changement de la référence images . L'immuabilité fonctionne certainement mieux pour la détection des changements.