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 } }
3 Réponses :
@Input() addImage() { this.ngZone.run(() => { this.images.push({ ciccio: 'piccio'}); //no rerender }); } Can you try injecting NgZone from @angular/core and run inside it?
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?
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 } }
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é?
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
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.
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'}];