前台在的菜单,须要向后台进行请求,可是这样就形成每次点击一个菜单都会从新请求,形成菜单会出现短暂闪烁的状况,因此考虑使用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...