Angular service的單例模式

問題描述

前臺在的菜單,須要向後臺進行請求,可是這樣就形成每次點擊一個菜單都會從新請求,形成菜單會出現短暫閃爍的狀況,因此考慮使用service的單例模式來解決這個問題。angularjs

service 單例模式

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在整個項目的模塊下是單例的了。

固然,此時使用原來在@NgModuleproviders的方式也是能夠的。

個人應用

個人目的是避免重複請求後臺,因此基本思路就是在一次請求後臺以後,將請求結果交給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...

相關文章
相關標籤/搜索