保持一個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
下的菜單就能夠(對擴展開放)。