无法使用BehaviorSubject

时间:2019-09-22 11:12:00

标签: javascript angular typescript ionic-framework ionic4

仅当我部署到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的原因和真正原因:

  • App.component.html和app.component.ts是共享的,因此,如果用户在应用程序的一个或其他页面中单击菜单打开器按钮,则没有问题,但是...我显示的方式其他信息,例如“ accountInfo”正在使用不在app.component.html内的头像(不共享),我想放在另一个地方而不是将其放在菜单中,这是因为我不知道如何使它在全球范围内像app.component.html一样可用,因此我必须在要使用它的每个page.html中编写该html。

,并且当用户点击头像时,我只需要在菜单中显示'accountInfo'项目并显然打开它(这就是为什么我只在标记为accountInfo时才调用this.menu.open的原因),而不是知道是否还有另一种更好的方法。

0 个答案:

没有答案