Comment puis-je recharger à nouveau le même composant dans Angular 2?
Voici mon code ci-dessous:
import { Component, OnInit, ElementRef, Renderer } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { productModel } from '../_models/index';
import { categoryListService } from '../_services/index';
@Component({
selector: 'app-product',
templateUrl: 'product.component.html',
styleUrls: ['product.component.css']
})
export class productComponent implements OnInit {
uidproduct: productModel;
param: number;
constructor(
private elementRef: ElementRef,
private route: ActivatedRoute,
private router: Router,
private categoryListService: categoryListService) { }
ngOnInit() {
this.route.params.subscribe(product => {
console.log('logging sub product obj', product);
});
this.uidproduct = JSON.parse(sessionStorage.getItem('product'));
var s = document.createElement("script");
s.type = "text/javascript";
s.src = "http://this/external/script/needs/to/be/loaded/each/time.js";
this.elementRef.nativeElement.appendChild(s);
}
nextproduct(){
let i = this.uidproduct.order;
this.categoryListService.findNextproduct(this.uidproduct);
this.param = ++i;
this.router.navigate([`/product/${this.param}`]);
}
}
nextproduct()
est lié à un événement de clic dans le modèle.
La uidproduct
est un objet JSON qui a un certain nombre de propriétés et je mets à jour le DOM avec {{uidproduct.classname}}
J'utilise ceci dans le modèle comme ceci:
<div id="selected-product" class="{{uidproduct.classname}}">
Lorsque je clique sur <button (click)="nextproduct()">
, la propriété de la classe du DOM change, mais je dois recharger le composant pour que le script externe ait un effet.
Vous pouvez utiliser *ngIf
pour rendre à nouveau le contenu d'un modèle:
@Component({
selector: '...',
template: `
<ng-container *ngIf="!rerender">
template content here
</ng-container>`
})
export class MyComponent {
rerender = false;
constructor(private cdRef:ChangeDetectorRef){}
doRerender() {
this.rerender = true;
this.cdRef.detectChanges();
this.rerender = false;
}
}
Je ne comprends pas pourquoi vous devez recharger le composant. Si vous vous liez aux différents champs de uidproduct
, le rechargement devrait alors actualiser les valeurs affichées dans le composant. Donc, le rechargement du composant ne fait que créer une surcharge.
S'il existe une excellente raison, non mentionnée ici, pour laquelle vous pensez avoir encore besoin de le faire, voici ce que vous faites:
Le problème est que vous devez attendre la fin de la première navigation avant de faire la deuxième.
Dans votre composant, importez NavigationEnd:
import { Router, NavigationEnd } from '@angular/router';
Et puis abonnez-vous dans votre constructeur:
constructor(private thingService: ThisThingService, private router: Router) {
router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
if (event.url === '/blank') {
this.router.navigate(['product']);
}
}
});
Notez que j'attends que NavigationEnd
se produise, puis vérifiez que je suis en train d'acheminer mon composant vierge. Si c'est le chemin du composant vierge, je retourne au produit. Si vous avez vraiment besoin de transmettre cet ID, stockez-le sur votre objet et ajoutez-le ici.
Au lieu d’acheminer votre projet vers la page de produit dans nextproduct()
, accédez à blank
.
this.router.navigate(['blank']);
Et cela devrait recharger votre composant parfaitement bien.
Le problème que j’ai intentionnellement laissé pour simplifier, c’est que l’appel subscribe
du constructeur s’exécutera à chaque rechargement. En tant qu’exercice pour le lecteur, sortez-le du constructeur et créez-en un service Nice, ou déplacez-le vers le constructeur de votre composant d’application, ou peut-être vers votre module de routage ou à tout autre endroit qui vous convient.