仅当我部署到android时才有这个问题(在iOS上未尝试过),如果我运行ionic serve来查看一切是否正常,则控制台不会抛出任何异常错误并且工作正常!,但是当我在android中尝试时,出现了问题:
无法读取未定义的属性“ next”
好,让我们进行描述,首先,我使用集成的离子型入门模板side_menu,我进行了一些样式修改(但仅此而已),所以让我们查看重现此问题所需的每个组件:< / p>
app.component.html :
在这里,我只在ion-menu元素中放置了ionDidClose事件(文档中的其他所有内容都不是必需的):
<ion-menu class = "shorted_menu" (ionDidClose) = "setDisplayMenuInfo('basicInfo')">
<!--More code here...-->
</ion-menu>
我在 app.component.ts 中有:
import { Component } from '@angular/core';
import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { enableProdMode } from '@angular/core';
import { MenuController } from '@ionic/angular';
import { Storage } from '@ionic/storage';
import { Router} from '@angular/router';
import { OneSignal } from '@ionic-native/onesignal/ngx';
import { AppPages } from '../global_modules/app_pages';
import { showInfo, setComponentBehaviorSubject } from '../global_modules/menu_functionality';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
enableProdMode();
@Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent {
public appPages;
public showInfo;
public currentDisplayMenu = 'basicInfo';
public behaviorSubject: BehaviorSubject<string>;
public behaviorSubjectObservable: Observable<any>;
public behaviorSubjectSubscription: Subscription;
public setComponentBehaviorSubject;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private oneSignal: OneSignal,
private storage: Storage,
private router: Router,
public menu: MenuController
)
{
this.initializeApp();
}
async setup(){
this.appPages = AppPages.pages;
this.showInfo = showInfo;
this.setComponentBehaviorSubject = setComponentBehaviorSubject;
this.userData = await this.getUserData();
this.userAvatar = this.userData.data.avatar_src.src && this.userData.data.avatar_src.src != "" ?
`${this.imagesRoute}${this.userData.data.avatar_src.src}`:
this.userAvatar;
this.behaviorSubject = new BehaviorSubject<string>('basicInfo');
this.behaviorSubjectObservable = this.behaviorSubject.asObservable();
this.setComponentBehaviorSubject(this.behaviorSubject);
this.behaviorSubjectSubscription = this.behaviorSubjectObservable.subscribe(data =>{
this.currentDisplayMenu = data;
});
}
ionViewWillLeave(){
this.behaviorSubjectSubscription.unsubscribe();
}
setDisplayMenuInfo(str){
this.showInfo(str);
}
async getUserData(){
return await this.storage.get('session_storage');
}
clearUserSession(){
this.oneSignal.removeExternalUserId();
this.storage.set('session_storage', null);
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleLightContent();
this.splashScreen.hide();
this.setup();
if(this.platform.is('cordova')){
this.setupPush();
}
this.storage.get('session_storage').then((res)=>{
if(res == null){
this.router.navigateByUrl('log-in');
}
});
});
}
setupPush(){
this.oneSignal.startInit(oneSignalData.appId, oneSignalData.googleProjectNumber);
this.oneSignal.inFocusDisplaying(this.oneSignal.OSInFocusDisplayOption.Notification);
this.oneSignal.handleNotificationReceived().subscribe(data => {
//Do something when notification received...
/*let msg = data.payload.body;
let title = data.payload.title;
let additionalData = data.payload.additionalData;*/
});
this.oneSignal.handleNotificationOpened().subscribe(data => {
let additionalData = data.notification.payload.additionalData;
//Actions to take when notification opened...
});
this.getUserData().then(res =>{
if(res && res.data.username != "" && res.data.type_user != ""){
this.oneSignal.setExternalUserId(`${res.data.username};${res.data.type_user}`);
}else{
this.oneSignal.removeExternalUserId();
}
})
this.oneSignal.endInit();
}
}
其中AppPages只是由app.component.ts导入的另一个类,并且在我内部具有公共静态属性页,这只是一个对象数组,并且在每个对象内部我都有一些菜单显示属性,例如标题和图标每个菜单项的另一个,还有另一个名为detailTag的属性,该标签使我可以根据属性轻松显示或隐藏菜单的某些内容:
currentDisplayMenu
of app.component.ts,因此一些菜单信息由detailTag属性中的'basicInfo'区分,这意味着当currentDisplayMenu包含内容'basicInfo'时,我将仅显示具有detailTag与'basicInfo匹配的菜单项',另一个分类是'accountInfo'。
好吧,其他需要的文件是 menu_functionality.ts ,如下所示:
import { BehaviorSubject } from 'rxjs';
var componentBehaviorSubject:BehaviorSubject<string>;
export function showInfo(tag){
switch(tag){
case 'basicInfo':
return componentBehaviorSubject.next('basicInfo');
break;
case 'accountInfo':
let CBS = componentBehaviorSubject.next('accountInfo');
this.menu.open();
return CBS;
break;
}
}
export function setComponentBehaviorSubject(behaviorSubject:BehaviorSubject<string>){
componentBehaviorSubject = behaviorSubject;
}
我为什么要调用this.menu.open();的原因仅当标记为'accountInfo'时才起作用,因为app.component.html和app.component.ts在应用程序中全局运行,并且如果用户仅单击侧面菜单按钮以打开它,就没有问题,并且没有需要把它放进去,但这是我使用BehaviorSubject的原因和真正原因:
,并且当用户点击头像时,我只需要在菜单中显示'accountInfo'项目并显然打开它(这就是为什么我只在标记为accountInfo时才调用this.menu.open的原因),而不是知道是否还有另一种更好的方法。