Как запустить функцию в ngOnInit() только один раз, а не снова при возврате из другого routerLink?

HomeComponent

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

retrieveData()
{
    // this.dataService.getData().subscribe(...);
}

Я получаю данные при загрузке компонента. Когда пользователь нажимает на другой routerLink, например, SettingsComponent и возвращается к HomeComponent, функция, конечно, вызывается снова, потому что компонент загружен снова. Но каждый раз, когда я возвращаюсь обратно к компоненту, он снова вызывает функцию, что создает слишком много нежелательных HTTP-запросов. Мне нужно предотвратить это и убедиться, что функция вызывается только в первый раз. Как мне это сделать? Должен ли я использовать какой-то другой компонент жизненного цикла?

1 ответ

Решение

Хорошо, я вижу, что вы используете сервис для загрузки данных, что является хорошим способом.

Затем вы можете просто где-то кешировать данные, а когда вернетесь к компоненту, проверить кеш на эти данные. Я думаю, что вы можете хранить данные непосредственно в вашем сервисе, который будет хранить их в памяти, или вы можете поместить их в localStorage

Итак, первый вариант будет выглядеть так:

data.service.ts

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

затем внутри 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
        });
    }
}

ВАЖНО: если вы используете этот подход, вы должны сделать свой сервис глобальным при объявлении его в app.module.ts -> provider

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

а потом не делать этого:

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

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

Подход localStorage

HomeComponenet

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 ...
    }
}

Оба подхода имеют ограничение, заключающееся в том, что вы не можете работать с огромными объемами данных, конечно, если вы не хотите взрывать браузеры пользователей, которые используют ваше приложение:)

Другие вопросы по тегам