Javascript 如何在不刷新整页的情况下更新组件 - Angular

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46047854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:19:32  来源:igfitidea点击:

How to Update a Component without refreshing full page - Angular

javascriptangularrefreshangular-components

提问by Aravinthan M

My Page structure is:

我的页面结构是:

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

How can I update/refresh the app-headercomponent, without refreshing the whole page?

如何在app-header不刷新整个页面的情况下更新/刷新组件?

I want to hide a "Sign-In" link in the header, once the user had successfully logged in. The header is common in all the components/routes.

一旦用户成功登录,我想在标题中隐藏“登录”链接。标题在所有组件/路由中都是通用的。

回答by Faisal

You can use a BehaviorSubjectfor communicating between different components throughout the app. You can define a data sharing service containing the BehaviorSubjectto which you can subscribe and emit changes.

您可以使用 aBehaviorSubject在整个应用程序的不同组件之间进行通信。您可以定义一个数据共享服务,其中包含BehaviorSubject您可以订阅和发出更改的 。

Define a data sharing service

定义数据共享服务

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class DataSharingService {
    public isUserLoggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
}

Add the DataSharingServicein your AppModuleproviders entry.

DataSharingService在您的AppModule提供者条目中添加。

Next, import the DataSharingServicein your <app-header>and in the component where you perform the sign-in operation. In <app-header>subscribe to the changes to isUserLoggedInsubject:

接下来,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;
        });
    }
}

In your <app-header>html template, you need to add the *ngIfcondition e.g.:

在您的<app-header>html 模板中,您需要添加*ngIf条件,例如:

<button *ngIf="!isUserLoggedIn">Login</button> 
<button *ngIf="isUserLoggedIn">Sign Out</button>

Finally, you just need to emit the event once the user has logged in e.g:

最后,您只需要在用户登录后发出事件,例如:

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

回答by Carsten

One of many solutions is to create an @Injectable()class which holds data that you want to show in the header. Other components can also access this class and alter this data, effectively changing the header.

许多解决方案之一是创建一个@Injectable()类来保存要在标题中显示的数据。其他组件也可以访问此类并更改此数据,从而有效地更改标题。

Another option is to set up @Input()variables and @Output()EventEmitters which you can use to alter the header data.

另一种选择是设置@Input()变量和@Output()EventEmitters,您可以使用它们来更改标题数据。

EditExamples as you requested:

根据您的要求编辑示例:

@Injectable()
export class HeaderService {
    private _data;
    set data(value) {
        this._data = value;
    }
    get data() {
        return this._data;
    }
}

in other component:

在其他组件中:

constructor(private headerService: HeaderService) {}

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

in header component:

在标题组件中:

let headerData;

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

I haven't actually tried this. If the get/set doesn't work you can change it to use a Subject();

我还没有真正尝试过这个。如果 get/set 不起作用,您可以将其更改为使用 Subject();

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

回答by Zze

Angular will automatically update a component when it detects a variable change .

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

So all you have to do for it to "refresh" is ensure that the header has a reference to the new data. This could be via a subscription within header.component.tsor via an @Inputvariable...

因此,您要“刷新”所需要做的就是确保标头具有对新数据的引用。这可能是通过订阅header.component.ts或通过@Input变量...



an example...

一个例子...

main.html

主文件

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

main.component.ts

main.component.ts

public headerData:int = 0;

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

header.html

标题.html

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

header.ts

头文件

@Input('header-data') data;

In the above example, the header will recieve the new data every 250ms and thus update the component.

在上面的例子中,头部将每 250 毫秒接收一次新数据,从而更新组件。



For more information about Angular's lifecycle hooks, see: https://angular.io/guide/lifecycle-hooks

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

回答by Rohan Fating

To update component

更新组件

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

You can use many approach like show hide using ngIf

您可以使用许多方法,例如使用 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>

You can also use 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>