保持一个ShareModule不变,实现前台器具用户和计量机构注销功能segmentfault
1.增长一个实体
2.判断是器具用户登陆,若是是则调用器具用户的注销,不然调用计量机构的注销(分别显示对应的菜单)数组
建立一个对象,订阅以前的$isLogin
若是是true
表示已登陆,而后调用对应注销方法,实现代码以下:app
// tobar数组的第一对象的位置,改变位置时需改变profileMenuIndex private profileMenuIndex = 0; tobars: Tobar[] = [ { title: 'Profile', class: 'fa fa-fw fa-user', state: false, onclickFn: () => { this.router.navigateByUrl('/main/personal'); } }, { title: 'Privacy', class: 'fa fa-fw fa-user-secret', state: true, onclickFn: () => { } }, { title: 'Settings', state: true, class: 'fa fa-fw fa-cog', onclickFn: () => { } }, { title: 'Logout', state: true, class: 'fa fa-fw fa-sign-out', onclickFn: () => { // 器具用户注销 this.unsubscribeMain = this.departmentService.$isLogin.subscribe((isInstrumentUserLogin) => { if (isInstrumentUserLogin) { this.departmentLogout(); } }); this.unsubscribeMain.unsubscribe(); // 计量机构注销 this.unsubscribeAdmin = this.systemService.$isLogin.subscribe((isAdminLogin) => { if (isAdminLogin) { this.logout(); } }); this.unsubscribeAdmin.unsubscribe(); } }, ]; ngOnInit(): void { this.departmentService.$isLogin.subscribe((isLogin) => { if (isLogin) { this.showProfileMenu(); } }); } // 改变state,true显示,false不显示 showProfileMenu(): void { this.tobars[this.profileMenuIndex].state = true; }
问题: 计量机构的注销并不起做用
发现:我订阅的计量机构$isLogin
不执行,因此说计量机构不能实现注销this
看了潘老师以前写的$isLogin
,发现俩个并不同
private _$isLogin = new
BehaviorSubject<boolean>(false);
public $isLogin = new
Subject<boolean>();
在此感谢张喜硕组长的帮忙!!spa
BehaviorSubject
与 Subject
区别Subject
建立一个Rxjs Subject
, 数据的类型是number
code
let subject1: Subject<number> = new Subject<number>();
而后咱们使用Subject
的next
方法来emit
(发射)1条数据component
subject1.next(1);
接下来对subject1
建立两个订阅,在subscription
中直接打印接受到的数据router
subject1.subscribe((res: number) => console.info("subjectA ", res)); subject1.subscribe((res: number) => console.info("subjectB ", res));
接下来我在发射两条数据对象
subject1.next(2); subject1.next(3);
结果ip
subjectA 2 subjectB 2 subjectA 3 subjectB 3
有时候我明明从数据源发射一个数据,但在订阅者拿到的值倒是undefined
或者null
, 这就是由于订阅者是在数据源发射以后建立的,天然没法接收到数据了。
假如咱们想在订阅者建立以后,不管何时都能拿到数据, 这应该怎么办呢? 那就要考虑使用BehaviourSubject
了。
BehaviourSubject
建立一个BehaviorSubject
, 默认值设为0. BehaviorSubject
须要给个默认值
而后发射一条数据1,建立一个订阅者,再发射一条数据2,再建立一个订阅者,最后发射一条数据3。
代码以下:
let subject2: BehaviorSubject<number> = new BehaviorSubject<number>(0); subject2.next(1); subject2.subscribe((res: number) => console.info("behavior-subjectA ", res)); subject2.next(2); subject2.subscribe((res: number) => console.info("behavior-subjectB ", res)); subject2.next(3);
结果
behavior-subjectA 1 behavior-subjectA 2 behavior-subjectB 2 behavior-subjectA 3 behavior-subjectB 3
因为BehaviorSubject
是能够存储最后一条数据或者初始默认值的, 因此不管订阅者何时订阅到数据源subject2
上, 都能接收到数据。
因此针对订阅者behavior-subjectA
, 他订阅的时候,数据流里最后一条数据是1, 他能当即接收到。 而后依次能接收到最新的数据2和3。
针对订阅者behavior-subjectB
, 他订阅的时候,数据流里最后一条数据是2, 他能当即接收到。 而后只能能接收到最新的数据3了。
上述来源Subject四种主题解析,四种Subject
特色以下:
因此说在订阅者,订阅他的时候以前的数据他是接受不到的,因此就出现了上述问题,修改以后
虽然是实现了,可是潘老师说这样思路是不对的,若是俩个用户同时登陆呢,而后我试了一下果真出现了问题,菜单也不是我想要的了(本身考虑的仍是不够啊!!)
实现代码以下(及供参考):
app.tobar.service.ts
export class AppTobarService { constructor(public systemService: SystemService, public departmentService: DepartmentService, public router: Router) { } public $tobars = new BehaviorSubject([ { title: 'Profile', class: 'fa fa-fw fa-user', onclickFn: () => { } }, { title: 'Privacy', class: 'fa fa-fw fa-user-secret', onclickFn: () => { } }, { title: 'Settings', class: 'fa fa-fw fa-cog', onclickFn: () => { } }, { title: 'Logout', class: 'fa fa-fw fa-sign-out', onclickFn: () => { } }, ]); }
app.tobar.component.ts
ngOnInit(): void { this.appTobarService.$tobars.subscribe((tobars: Tobar[]) => { this.tobars = tobars; }); }
tobar.service.ts
export class TobarService extends AppTobarService { getTobar(): any[] { return [ { title: '我的中心', class: 'fa fa-fw fa-user', onclickFn: () => { this.router.navigateByUrl('/main/personal'); } }, { title: '注销', class: 'fa fa-fw fa-sign-out', onclickFn: () => { this.departmentService.loginOut(); } }, ]; } }
main.component.ts
ngOnInit() { // 初始化顶部菜 this.appTobarService.$tobars.next(this.tobarService.getTobar()); }
tobar.service.ts
export class TobarService extends AppTobarService { getTobar(): any[] { return [ { title: '系统设置', class: 'fa fa-fw fa-cog', onclickFn: () => { this.router.navigateByUrl('/admin/system'); } }, { title: '注销', class: 'fa fa-fw fa-sign-out', onclickFn: () => { this.systemService.logout(); } }, ]; } }
admin.component.ts
ngOnInit() { // 初始化顶部菜单 this.appTobarService.$tobars.next(this.tobarService.getTobar()); }
1.假设我以前的思路可行,可是在以后修改起来会很麻烦,增长一个菜单时会有不少不定的因素产生(加上时间问题,当时怎么写的已经不记得了,会产生不可控的错误)。
2.以后的思路,也就是潘老师说的一句话对扩展开放,对修改关闭
,及时之后增长菜单,Share(模板)中永远保持不变(对修改关闭),想增长菜单只需改Main
或Admin
下的菜单就能够(对扩展开放)。