在 Ionic 2 中动态更新侧边菜单

Posted

技术标签:

【中文标题】在 Ionic 2 中动态更新侧边菜单【英文标题】:Dynamically Update Side Menu in Ionic 2 【发布时间】:2017-07-30 06:54:11 【问题描述】:

我在 ionic 2 中有一个侧边菜单,我正在尝试在用户登录后对其进行更新。我正在使用来自 ionic-angular 的事件。这是我所做的。

app.component.ts

import  Component, ViewChild  from '@angular/core';
import  Platform, Nav, AlertController, MenuController, Events  from 'ionic-angular';
import  HomePage  from '../pages/home/home';

@Component(
  templateUrl: 'app.html'
)
export class MyApp 

  rootPage:any = HomePage;
  logoutAlert:any;
  currentUser:any;

  @ViewChild('nav') nav: Nav;

  constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen, public storage: Storage, public alertCtrl: AlertController, public menuCtrl: MenuController, public events: Events) 

    this.currentUser = 
      name: "Guest",
      username: "not logged in"
    ;

    this.logoutAlert = this.alertCtrl.create(
      message: "Sure you want to log out?",
      buttons: [text: "Yes", handler: () => 
        this.logoutUser();
      , text:"No", role: "cancel"]
    );

    this.menuCtrl.enable(false);

    platform.ready().then(() => 
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      statusBar.styleDefault();
      splashScreen.hide();
    );
  

  ionViewWillLoad() 

    this.events.subscribe("userloggedin", (user) => 
        this.currentUser = JSON.parse(user);
    );

  

app.html

<ion-menu [content]="content">
    <ion-item>
        <ion-avatar>
            <img src="../assets/letters/currentUser.name.svg">
        </ion-avatar>
        <p>
            currentUser.username
        </p>
    </ion-item>
</ion-menu>

<ion-nav id="nav" [root]="rootPage" #content></ion-nav>

home.ts

import  Component, ViewChild  from '@angular/core';
import  FormBuilder, FormControl, FormGroup  from '@angular/forms';
import  NavController, Slides, LoadingController, Events  from 'ionic-angular';
import  Storage  from '@ionic/storage';
import  HttpProvider  from '../../providers/http/http';
import  TabsPage  from '../tabs/tabs';

@Component(
  selector: 'page-home',
  templateUrl: 'home.html'
)
export class HomePage 

    @ViewChild('signSlides') signSlides: Slides;

    currentUser: any;
    loading:any;
    signinForm:any;

  constructor(public navCtrl: NavController,public formBuilder: FormBuilder, public storage: Storage, public httpProvider: HttpProvider, public loadingCtrl: LoadingController, public events: Events) 
    this.signinForm = formBuilder.group(
        email: [''],
        password: ['']
    );

    this.loading = this.loadingCtrl.create(
        content: "<ion-spinner></ion-spinner>"
    );
  

  signinUser() 
    let params = 
        username: this.signinForm.value.email,
        password: this.signinForm.value.password
    ;
    this.httpProvider.loginUser(params).subscribe(
        results => 
            this.loading.present();
            this.currentUser = results['_body'];
        ,

        err => 
            alert("Oops! An error occured!");
        ,
        () => 
            this.storage.set("currentUser", this.currentUser);
            this.loading.dismiss();
            this.navCtrl.setRoot(TabsPage);
        
    );
  

    this.httpProvider.registerUser(params).subscribe(
        results => 
            this.loading.present();
            this.currentUser = results['_body'];
        ,
        err => 
            alert("Oops! An error occured!");
        ,
        () => 
            this.storage.set("currentUser", this.currentUser);
        this.events.publish("userloggedin", this.currentUser);
            this.loading.dismiss();
            this.navCtrl.setRoot(TabsPage);
        
    );

  

  firstLetter(s:string) 
    s = s.toLowerCase();
    return s.charAt(0);
  


我尝试将 events.subscribe 放在 ionViewDidLoad、ionViewDidEnter 和 ngOnInit 中,但对我没有任何效果。来自 home.ts 的数据正在保存在存储中,但我不知道为什么它不在 ionic 菜单中更新。

【问题讨论】:

这是一个评论,而不是一个答案——我建议尝试使用 Redux 模式,例如,ngrx,并在一个中心位置管理状态的所有方面。然后,您的组件(在本例中为 MyApp)将订阅用户状态,并显示登录的用户名,或者如果没有用户登录,则显示一些默认字符串。我自己刚开始做。 【参考方案1】:

建议给事件传递一个字符串值,而不是一个Json对象, this.events.publish("userloggedin", this.currentUser);` 如果 this.currentUser 是 home.ts 中上述代码中的字符串,那么它应该可以按预期工作。 而且在app.component.ts的构造函数里面,你也可以这样放代码。

this.events.subscribe("userloggedin", (user) => 
    this.currentUser = user
);

【讨论】:

【参考方案2】:

app.component 没有与其他页面相同的回调,因此您必须将代码移至类构造函数:

@Component(
  templateUrl: 'app.html'
)
export class MyApp 
  constructor(private events: Events) 
    this.events.subscribe("userloggedin", (user) => this.currentUser = user);
  

您不需要JSON.parse(user),因为事件不会将对象转换为字符串。

【讨论】:

以上是关于在 Ionic 2 中动态更新侧边菜单的主要内容,如果未能解决你的问题,请参考以下文章

在 React 中动态更新导航栏和侧边栏的最佳方法是啥?

在 ionic 2 中使用带有侧边菜单的 nav.push

ionic 2 标题不显示侧边菜单“栏”

如何在 ionic2-angular2 中动态切换菜单的一侧?

ionic 2 + angular 2 - 选项卡 + 侧边菜单

Ionic 2 - 用户登录后侧边菜单更改