Как обновить компонент без обновления всей страницы-Angular



Структура моей страницы:



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


Как я могу обновить / обновить компонент app-header, не обновляя всю страницу?



Я хочу скрыть ссылку "Вход" в заголовке, Как только пользователь успешно вошел в систему. Заголовок является общим для всех компонентов / маршрутов.

1189   4  

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

    Ничего не найдено.