3
votes

I have a Navigation bar in Angular 2. It works like below.

<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
  <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <a class="navbar-brand" href="#">App</a>
  <div class="collapse navbar-collapse" id="navbarNav">
    <ul class="navbar-nav">
      <li class="nav-item">
        <a routerLink="/dashboard" routerLinkActive="active" class="nav-link">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a routerLink="/grid" routerLinkActive="active" class="nav-link" >Grid</a>
      </li>
      <li class="nav-item">
        <a routerLink="/reporting" routerLinkActive="active" class="nav-link" >Reporting</a>
      </li>
    </ul>
  </div>
</nav>

And each tab loads 1 component. So dashboard loads DashboardComponent and grid loads a GridComponent.

Both component mentioned above gets data from a data.service.ts. My question: is there a way to click on dashboard (it loads after 3 seconds), and then navigate away from dashboard tab to the grid tab. Then when I go back to the dashboard tab, can it not reload and take the 3 seconds time again??

The app we wrote in Angular 1.5 doesn't have the above problem. The issue is if the user is switching between dashboard and grid, it takes a lot of time.

I looked at the following questions asked here: Bootstrap's tabs with data-toggle cause reload in angularjs

Angular2 router.navigate refresh page

They both don't solve my problem. first question is for angular 1. and the second question, when I make my nav items into type="button", the reloading is still happening.

2

2 Answers

1
votes

I suspect the reason your components are taking so long to reload is because they depend on services that fetch data and take a few seconds to do so. If your components get data asynchronously from a service via an http request on initialization, that request will fire every time the component is created and shown to the user.

The solution to this is to create a cache for your service. Once your service fetches the data it requires, it should cache it as a variable. Then, when the service is asked to make the same request, it can check to see if it already has a result and pass back that result rather than making the full http request again.

If your slow component load is because of a caching problem, these answers may help: caching results with angular2 http service.

Also, here's an example of a service I just wrote that caches its result for future requests:

import { Injectable } from "@angular/core";
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class RhymeService {

    constructor(private http: Http) { }

    cachedData: any = {};

    search(term: string): Observable<string[]> {
        if (term in this.cachedData) {
            return Observable.of(this.cachedData[term]);
        }

        let rhymeUrl = `https://api.datamuse.com/words?rel_rhy=${term}`;

        return this.http.get(rhymeUrl).map(response => {
            let words = response.json().map((rhyme) => {
                return rhyme.word;
            });
            this.cachedData[term] = words;
            return <string[]>words;
        });
    }
}

Note that this will prevent your app from loading new data on a component reload unless you handle updating the cache from time to time.

1
votes

Loading time was not the issue.Because data set is relatively big. Problem is solved by Ng Bootstrap -> tabs -> destroyOnHide set to false.

https://ng-bootstrap.github.io/#/components/tabs

When you need to update data for the component, use ngOnChanges