我如何只在ngOnInit()上运行一个函数,而不是从另一个routerLink返回时再次运行?

ano*_*nym 1 lifecycle-hook ngoninit angular

HomeComponent

ngOnInit()
{
    console.log('loaded');
    this.retrieveData();
}

retrieveData()
{
    // this.dataService.getData().subscribe(...);
}
Run Code Online (Sandbox Code Playgroud)

组件加载时,我正在检索数据。routerLink例如,当用户单击另一个,SettingsComponent然后返回时HomeComponent,当然会再次调用该函数,因为该组件已再次加载。但是,每当我返回该组件时,它都会再次调用该函数,这会创建太多不需要的HTTP请求。我需要防止这种情况,并确保仅在第一次调用该函数。我该怎么做呢?我应该使用其他组件生命周期挂钩吗?

cod*_*tex 5

好的,我看到您正在使用服务来加载数据,这是一种好方法。

然后,您可以简单地将数据缓存在某个位置,当您返回组件时,请检查该数据的缓存。我认为您可以将数据直接存储在服务中,将其保留在内存中,也可以将其放置在localStorage中

因此,第一个选项如下所示:

数据服务

export class DataService {

    private data: any[];

    setData(data:any[]){
        this.data = data;
    } 

    getData(){
        return this.data || [];
    }

    hasData(){
        return this.data && this.data.length;    
    }  

    getData(){
        // your implementation here 
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在HomeComponent内部

retrieveData(){
    if(this.dataService.hasData()){
         // this will get the data which was previously stored in the memory
         // and there will be no HTTP request
         let data = this.dataService.getData();
         // do something with data now ...
    }else{
        // old code 
        this.dataService.getData().subscribe(response => {
            // but this time safe the data for future use
            this.dataService.setData(response.data);   
        }, error => {
            // handle errors
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

重要提示:如果使用此方法,则应在app.module.ts- > provider中声明服务时使其成为全局服务

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule
    ],
    providers: [
        DataService   <---------- SEE HERE
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

然后不这样做:

@Component({
    selector: 'home',
    templateUrl: '...',
    styleUrls: ['...'],
    providers: [
        DataService     <---- THEN DON'T put in component's providers
    ]
})
export class HomeComponent{ ... }
Run Code Online (Sandbox Code Playgroud)

=============================================

localStorage方法

家庭网络

retrieveData()
{
    let data = localStorage.getItem('yourDataName');
    if (data === null){
        // old code 
        this.dataService.getData().subscribe(response => {
            // but this time safe the data for future use in localStorage
            localStorage.setItem('yourDataName', response.data); 
        }, error => {
            // handle errors
        });
    } else {
        // seems that you already loaded this data 
        // do something with this data ...
    }
}
Run Code Online (Sandbox Code Playgroud)

两种方法都有一个局限性,那就是您不能处理大量数据,当然,如果您不想让正在使用您的应用程序的用户的浏览器崩溃:)