Comment mettre à jour un composant sans rafraîchir toute la page-Angular
ma structure de Page est:
<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>
Comment puis-je mettre à jour/rafraîchir le app-header
composant, sans rafraîchir toute la page?
je veux cacher un lien de connexion dans l'en-tête, une fois que l'utilisateur s'est connecté avec succès. L'en-tête est commun dans tous les components/routes.
4 réponses
Vous pouvez utiliser un BehaviorSubject
pour communiquer au sein des différents composants de l'application. Vous pouvez définir un service de partage de données contenant les BehaviorSubject
auquel vous pouvez vous abonner et émettre des modifications.
définir un service de partage de données
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable()
export class DataSharingService {
public isUserLoggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
}
Ajouter DataSharingService
dans votre AppModule
entrée des fournisseurs.
Ensuite, importez l' DataSharingService
dans votre <app-header>
et dans le composant où vous effectuez l'opération de connexion. <app-header>
abonnez-vous aux modifications de isUserLoggedIn
sujet:
import { DataSharingService } from './data-sharing.service';
export class AppHeaderComponent {
// Define a variable to use for showing/hiding the Login button
isUserLoggedIn: boolean;
constructor(private dataSharingService: DataSharingService) {
// Subscribe here, this will automatically update
// "isUserLoggedIn" whenever a change to the subject is made.
this.dataSharingService.isUserLoggedIn.subscribe( value => {
this.isUserLoggedIn = value;
});
}
}
Dans votre <app-header>
modèle html, vous devez ajouter le *ngIf
condition par exemple:
<button *ngIf="!isUserLoggedIn">Login</button>
<button *ngIf="isUserLoggedIn">Sign Out</button>
Enfin, vous avez juste besoin d'émettre l'événement une fois que l'utilisateur s'est connecté.e.g:
someMethodThatPerformsUserLogin() {
// Some code
// .....
// After the user has logged in, emit the behavior subject changes.
this.dataSharingService.isUserLoggedIn.next(true);
}
Angular mettra automatiquement à jour un composant lorsqu'il détecte un changement de variable .
Donc tout ce que vous avez à faire pour "actualiser" est de s'assurer que l'en-tête a une référence pour les nouvelles données. Cela peut se faire via un abonnementheader.component.ts
ou par @Input
variable...
une exemple...
main.html
<app-header [header-data]="headerData"></app-header>
main.composant.ts
public headerData:int = 0;
ngOnInit(){
setInterval(()=>{this.headerData++;}, 250);
}
en-tête.html
<p>{{data}}</p>
en-tête.ts
@Input('header-data') data;
dans l'exemple ci-dessus, l'en-tête recevra les nouvelles données tous les 250ms et mettra donc à jour le composant.
pour plus d'information sur les crochets de cycle de vie D'Angular, voir: https://angular.io/guide/lifecycle-hooks
Une des nombreuses solutions est de créer un @Injectable()
classe qui contient les données que vous voulez afficher dans l'en-tête. D'autres composants peuvent également accéder à cette classe et modifier ces données, changeant ainsi l'en-tête.
une autre option est de configurer @Input()
variables et @Output()
EventEmitters que vous pouvez utiliser pour modifier les données d'en-tête.
Modifier Exemples comme vous l'avez demandé:
@Injectable()
export class HeaderService {
private _data;
set data(value) {
this._data = value;
}
get data() {
return this._data;
}
}
dans l'autre composante:
constructor(private headerService: HeaderService) {}
// Somewhere
this.headerService.data = 'abc';
dans composant d'en-tête:
let headerData;
constructor(private headerService: HeaderService) {
this.headerData = this.headerService.data;
}
je n'ai pas réellement essayé. Si les get/set ne fonctionne pas, vous pouvez le modifier pour utiliser un Objet();
// Simple Subject() example:
let subject = new Subject();
this.subject.subscribe(response => {
console.log(response); // Logs 'hello'
});
this.subject.next('hello');
pour mettre à jour le component
@Injectable()
export class LoginService{
private isUserLoggedIn: boolean = false;
public setLoggedInUser(flag) { // you need set header flag true false from other components on basis of your requirements, header component will be visible as per this flag then
this.isUserLoggedIn= flag;
}
public getUserLoggedIn(): boolean {
return this.isUserLoggedIn;
}
Login Component ts
Login Component{
constructor(public service: LoginService){}
public login(){
service.setLoggedInUser(true);
}
}
Inside Header component
Header Component ts
HeaderComponent {
constructor(public service: LoginService){}
public getUserLoggedIn(): boolean { return this.service.getUserLoggedIn()}
}
template of header component: Check for user sign in here
<button *ngIf="getUserLoggedIn()">Sign Out</button>
<button *ngIf="!getUserLoggedIn()">Sign In</button>
vous pouvez utiliser plusieurs approches comme show hide en utilisant ngIf
App Component ts
AppComponent {
public showHeader: boolean = true;
}
App Component html
<div *ngIf='showHeader'> // you show hide on basis of this ngIf and header component always get visible with it's lifecycle hook ngOnInit() called all the time when it get visible
<app-header></app-header>
</div>
<router-outlet></router-outlet>
<app-footer></app-footer>
vous pouvez aussi utiliser le service
@Injectable()
export class AppService {
private showHeader: boolean = false;
public setHeader(flag) { // you need set header flag true false from other components on basis of your requirements, header component will be visible as per this flag then
this.showHeader = flag;
}
public getHeader(): boolean {
return this.showHeader;
}
}
App Component.ts
AppComponent {
constructor(public service: AppService){}
}
App Component.html
<div *ngIf='service.showHeader'> // you show hide on basis of this ngIf and header component always get visible with it's lifecycle hook ngOnInit() called all the time when it get visible
<app-header></app-header>
</div>
<router-outlet></router-outlet>
<app-footer></app-footer>