问题描述
前台在的菜单,需要向后台进行请求,但是这样就造成每次点击一个菜单都会重新请求,造成菜单会出现短暂闪烁的情况,所以考虑使用service的单例模式
来解决这个问题。
service 单例模式
在angularjs
中,service默认
都是单例的,但是在angular
中,取消了这种默认。虽然我们说单例模式是好的,但是很多时候我们真的需要service是单例的吗?
比如我们经常使用的表格,大部分情况下,我们只是需要将信息展示出来,并不需要使用service对其进行缓存,因为它不会被别的模块所使用。
那么,在angular
中如何使service
为单例的呢?
实现
其实,在angular6
之前,如何我们想声明一个service
供全局使用,是这样设置的:
服务:
export class TestService { }
根模块:
@NgModule({
declarations: [...],
providers: [TestService],
bootstrap: [AppComponent]
})
export class AppModule {}
我们需要在@NgModule
中去声明providers
,将service
共全局使用,成为单例。
但是从angular6
开始,单例模式又变成了一个首选方式。
所以,只要我们使用angular-cli
的命令创建service的时候,就会默认创建如下部分:
@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...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。