前臺在的菜單,須要向後臺進行請求,可是這樣就形成每次點擊一個菜單都會從新請求,形成菜單會出現短暫閃爍的狀況,因此考慮使用service的單例模式
來解決這個問題。angularjs
在angularjs
中,service默認
都是單例的,可是在angular
中,取消了這種默認。雖然咱們說單例模式是好的,可是不少時候咱們真的須要service是單例的嗎?bootstrap
好比咱們常常使用的表格,大部分狀況下,咱們只是須要將信息展現出來,並不須要使用service對其進行緩存,由於它不會被別的模塊所使用。segmentfault
那麼,在angular
中如何使service
爲單例的呢?緩存
其實,在angular6
以前,如何咱們想聲明一個service
供全局使用,是這樣設置的:ide
服務:ui
export class TestService { }
根模塊:this
@NgModule({ declarations: [...], providers: [TestService], bootstrap: [AppComponent] }) export class AppModule {}
咱們須要在@NgModule
中去聲明providers
,將service
共全局使用,成爲單例。code
可是從angular6
開始,單例模式又變成了一個首選方式。get
因此,只要咱們使用angular-cli
的命令建立service的時候,就會默認建立以下部分:it
@Injectable({ providedIn: 'root', })
這時,就聲明該service
在整個項目的模塊下是單例的了。
固然,此時使用原來在@NgModule
中providers
的方式也是能夠的。
個人目的是避免重複請求後臺,因此基本思路就是在一次請求後臺以後,將請求結果交給service
保管,而後,而後下次請求就直接獲取service中的數據就能夠了。
@Injectable({ providedIn: 'root', }) export class MenuService { private baseUrl = 'menu'; private currentMenuList: Array<Menu>; // 這裏存儲全部的菜單 constructor(private http: HttpClient) { } /** * 請求後臺,獲取全部菜單 */ getAll() { return this.http.get<Menu[]>(this.baseUrl); } /** * 設置當前菜單列表 * @param menuList 菜單列表 */ setMenuList(menuList: Array<Menu>) { this.currentMenuList = menuList; } /** * 獲取當前菜單列表 */ getMenuList() { return this.currentMenuList; } }
export class LeftControlComponent implements OnInit { menuList: Menu[]; // 菜單 constructor(private userService: UserService, private menuService: MenuService) { } ngOnInit() { this.initMenu(); } /** * 初始化菜單 */ initMenu() { // 當前菜單爲空的時候,從新請求菜單 if (!this.menuService.getMenuList() || this.menuService.getMenuList().length === 0) { this.userService.getCurrentLoginUser() .subscribe((data: User) => { this.menuList = data.role.menuList; // 將獲取的菜單交由service保存 this.menuService.setMenuList(this.menuList); }, () => console.log('network error!')); } else { // 直接使用保存的菜單 this.menuList = this.menuService.getMenuList(); } } }
這樣,只用在登陸進行系統的時候獲取一次菜單,後面都不用進行向後臺的請求了。閃爍的問題也就消失了。
相關參考:
https://segmentfault.com/a/11...
https://angular.cn/guide/sing...