Как обновить компонент без обновления всей страницы-Angular
Структура моей страницы:
<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>
Как я могу обновить / обновить компонент app-header, не обновляя всю страницу?
Я хочу скрыть ссылку "Вход" в заголовке, Как только пользователь успешно вошел в систему. Заголовок является общим для всех компонентов / маршрутов.
4 ответов:
Вы можете использовать
BehaviorSubjectдля общения в рамках различных компонентов по всему приложению. Можно определить службу обмена данными, содержащуюBehaviorSubjectна которые вы можете подписаться и внести изменения.Определите службу обмена данными
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable() export class DataSharingService { public isUserLoggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); }Добавить
DataSharingServiceв вашемAppModuleвход провайдеров.Далее импортируйте
DataSharingServiceв свой<app-header>и в компонент, в котором выполняется операция входа. В<app-header>подписаться к изменениям в темеisUserLoggedIn: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; }); } }В вашем html-шаблоне
<app-header>необходимо добавить условие*ngIf, например:<button *ngIf="!isUserLoggedIn">Login</button> <button *ngIf="isUserLoggedIn">Sign Out</button>Наконец, вам просто нужно выдать событие, как только пользователь вошел в систему, например:
someMethodThatPerformsUserLogin() { // Some code // ..... // After the user has logged in, emit the behavior subject changes. this.dataSharingService.isUserLoggedIn.next(true); }
Angular автоматически обновит компонент при обнаружении изменения переменной .
Таким образом, все, что вам нужно сделать для его "обновления", - это убедиться, что заголовок содержит ссылку на новые данные. Это может быть подписка внутри переменнойheader.component.tsили через переменную@Input...
Пример...
Главное.html
<app-header [header-data]="headerData"></app-header>Главное.деталь.ts
public headerData:int = 0; ngOnInit(){ setInterval(()=>{this.headerData++;}, 250); }Заголовок.html
<p>{{data}}</p>Заголовок.ts
@Input('header-data') data;В в приведенном выше примере заголовок будет получать новые данные каждые 250 мс и таким образом обновлять компонент.
Для получения дополнительной информации о крючках жизненного цикла Angular см.: https://angular.io/guide/lifecycle-hooks
Одним из многих решений является создание класса
@Injectable(), который содержит данные, которые вы хотите отобразить в заголовке. Другие компоненты также могут обращаться к этому классу и изменять эти данные, эффективно изменяя заголовок.Еще одним вариантом является настройка
@Input()переменные и@Output()EventEmitters, которые вы можете использовать, чтобы изменить данные заголовка.Отредактируйте примеры, как вы просили:
@Injectable() export class HeaderService { private _data; set data(value) { this._data = value; } get data() { return this._data; } }В другом компоненте:
constructor(private headerService: HeaderService) {} // Somewhere this.headerService.data = 'abc';В компоненте заголовка:
let headerData; constructor(private headerService: HeaderService) { this.headerData = this.headerService.data; }У меня нет на самом деле попробовал это. Если get / set не работает, вы можете изменить его на использование Subject ();
// Simple Subject() example: let subject = new Subject(); this.subject.subscribe(response => { console.log(response); // Logs 'hello' }); this.subject.next('hello');
Обновить компонент
@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>Вы можете использовать много подходов, таких как show hide с помощью 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>Вы также можете использовать сервис
@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>
Comments