web-dev-qa-db-fra.com

Comment mettre à jour un composant sans rafraîchir la pleine page - Angular

Ma structure de page est:

<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>

Comment puis-je mettre à jour/actualiser le app-header composant, sans rafraîchir la page entière?

Je souhaite masquer un lien "Connexion" dans l'en-tête, une fois que l'utilisateur s'est connecté avec succès. L'en-tête est commun à tous les composants/itinéraires.

41
Aravinthan M

Vous pouvez utiliser un BehaviorSubject pour communiquer entre les différents composants de l'application. Vous pouvez définir un service de partage de données contenant 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);
}

Ajoutez DataSharingService dans votre entrée de fournisseurs AppModule.

Ensuite, importez le DataSharingService dans votre <app-header> et dans le composant où vous effectuez la connexion. Dans <app-header> abonnez-vous aux modifications apportées à 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, il vous suffit d'émettre l'événement une fois que l'utilisateur s'est connecté, par exemple:

someMethodThatPerformsUserLogin() {
    // Some code 
    // .....
    // After the user has logged in, emit the behavior subject changes.
    this.dataSharingService.isUserLoggedIn.next(true);
}
55
Faisal

L'une des nombreuses solutions consiste à créer une classe @Injectable() qui contient les données que vous souhaitez afficher dans l'en-tête. D'autres composants peuvent également accéder à cette classe et modifier ces données, modifiant efficacement l'en-tête.

Une autre option consiste à configurer les variables @Input() 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 un autre composant:

constructor(private headerService: HeaderService) {}

// Somewhere
this.headerService.data = 'abc';

dans le composant d'en-tête:

let headerData;

constructor(private headerService: HeaderService) {
    this.headerData = this.headerService.data;
}

Je n'ai pas vraiment essayé ça. Si le get/set ne fonctionne pas, vous pouvez le changer pour utiliser un Subject ();

// Simple Subject() example:
let subject = new Subject();
this.subject.subscribe(response => {
  console.log(response); // Logs 'hello'
});
this.subject.next('hello');
2
Carsten

Pour mettre à jour le composant

 @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 de nombreuses 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 également 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>
1
Rohan Fating

Angular mettra automatiquement à jour un composant lorsqu'il détecte un changement de variable.

Donc, tout ce que vous avez à faire pour qu'il "se rafraîchisse" est de vous assurer que l'en-tête a une référence aux nouvelles données. Cela pourrait être via un abonnement au sein de header.component.ts ou via un @Input variable ...


un exemple...

main.html

<app-header [header-data]="headerData"></app-header>

main.component.ts

public headerData:int = 0;

ngOnInit(){
    setInterval(()=>{this.headerData++;}, 250);
}

header.html

<p>{{data}}</p>

header.ts

@Input('header-data') data;

Dans l'exemple ci-dessus, l'en-tête recevra les nouvelles données toutes les 250 ms et mettra ainsi à jour le composant.


Pour plus d'informations sur les crochets de cycle de vie d'Angular, voir: https://angular.io/guide/lifecycle-hooks

1
Zze