Как обновить компонент без обновления полной страницы-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;
});
}
}
в своем <app-header>
HTML-шаблон, вам нужно добавить *ngIf
условии, например:
<button *ngIf="!isUserLoggedIn">Login</button>
<button *ngIf="isUserLoggedIn">Sign Out</button>
наконец, вам просто нужно испустить событие, как только пользователь вошел в систему e.g:
someMethodThatPerformsUserLogin() {
// Some code
// .....
// After the user has logged in, emit the behavior subject changes.
this.dataSharingService.isUserLoggedIn.next(true);
}
Angular автоматически обновит компонент при обнаружении изменения переменной .
поэтому все, что вам нужно сделать, чтобы "обновить", это убедиться, что заголовок имеет ссылку на новые данные. Это может быть через подписку в header.component.ts
или через @Input
переменной...
an образец...
main.HTML-код
<app-header [header-data]="headerData"></app-header>
main.деталь.ТС
public headerData:int = 0;
ngOnInit(){
setInterval(()=>{this.headerData++;}, 250);
}
.HTML-код
<p>{{data}}</p>
.ТС
@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';
in компонент заголовка:
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>
вы можете использовать много подходов, таких как Показать Скрыть с помощью 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>