代码之家  ›  专栏  ›  技术社区  ›  Aravinthan M Rohan Fating

如何在不刷新整个页面的情况下更新组件-角度

  •  51
  • Aravinthan M Rohan Fating  · 技术社区  · 7 年前

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

    如何更新/刷新 app-header 组件,而不刷新整个页面?

    我想在用户成功登录后,在标题中隐藏一个“登录”链接。标头在所有组件/路由中都很常见。

    6 回复  |  直到 6 年前
        1
  •  84
  •   FAISAL    4 年前

    BehaviorSubject 用于在整个应用程序的不同组件之间进行通信。您可以定义一个包含 您可以订阅并发出更改。

    定义数据共享服务

    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs';
    
    @Injectable()
    export class DataSharingService {
        public isUserLoggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
    }
    

    DataSharingService 在你的 AppModule 提供者条目。

    接下来,导入 数据共享服务 在你的 <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模板,您需要添加 *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);
    }
    
        2
  •  3
  •   Jayanth Bhansali    4 年前

    为了定期刷新组件,我发现这是最好的方法。

    ngOnInit(): void {
      setTimeout(() => { this.ngOnInit() }, 1000 * 10)
    }
    //10 is the number of seconds
    
        3
  •  2
  •   Carsten    7 年前

    @Injectable() 类,该类保存要在标头中显示的数据。其他组件也可以访问该类并更改该数据,从而有效地更改标头。

    另一种选择是设置 @Input() 变量和 @Output()

    @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');
    
        4
  •  1
  •   Zze    7 年前

    Angular在检测到变量变化时将自动更新组件。

    header.component.ts 或通过 @Input 变量


    主要的html

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

    public headerData:int = 0;
    
    ngOnInit(){
        setInterval(()=>{this.headerData++;}, 250);
    }
    

    标题。html

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

    @Input('header-data') data;
    

    在上述示例中,报头将每隔250ms接收一次新数据,从而更新组件。


    有关Angular的生命周期挂钩的更多信息,请参阅: https://angular.io/guide/lifecycle-hooks

        5
  •  1
  •   Aravinthan M Rohan Fating    6 年前

    更新组件的步骤

     @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>
    

    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>
    
        6
  •  1
  •   EliuX    3 年前

    您只需要通知Angular使用 ChangeDetectorRef . 因此,在标题组件中:

    constructor(private cd: ChangeDetectorRef) {}
    
    loggedUserEvent(user: User): void {
      this.username = user.username; 
      this.enableDisconnectButton();
    
      //... Add more logic to it
    
      this.cd.detectChanges();
    }