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

相关文章
相关标签/搜索