【问题标题】:How to use Ionic2 Events如何使用 Ionic2 事件
【发布时间】:2017-06-10 05:07:10
【问题描述】:

我的登录服务中创建的登录事件的结果不一致。当用户登录或注销时,订阅页面上的事件不会被选中,相应地更改页面上的链接。

更新 经过更多测试后,我发现每个页面都可以订阅,但只有在首先输入之后。换句话说,如果我在登录之前访问 pageWithLink.ts,那么该页面将正确读取订阅更新,但如果我在访问该页面之前登录,它将忽略订阅更新。

tabs.ts

import { Component } from '@angular/core';
import { NavParams } from 'ionic-angular';

import { page1 } from '../page1';
import { page2 } from '../page2';
import { page3 } from '../page3';
@Component({
  templateUrl: 'tabs.html'
})
export class Tabs {
  index:any;
  tab1Root: any = page1;
  tab2Root: any = page2;
  tab3Root: any = page3;

  constructor(public navParams: NavParams) {
    if(navParams.get('index') === undefined || navParams.get('index') === null){
        this.index = "0";
    } else {
        this.index = navParams.get('index');
    }
  }
}

app.module.ts

import { NgModule, ErrorHandler } from '@angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';

import { Tabs } from '../tabs';
import { page1 } from '../page1';
import { page2 } from '../page2';
import { page3 } from '../page3';

import { LoginService } from '../services/loginService';

@NgModule({
  declarations: [
    page1,
    page2,
    page3,
    Tabs
],
  imports: [
    IonicModule.forRoot(MyApp, {
      swipeBackEnabled: true
    })
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    page1,
    page2,
    page3,
    Tabs
],
  providers: [LoginService]
})
export class AppModule {}

loginService.ts

import { Injectable } from '@angular/core';
import { Events } from 'ionic-angular';
import { AlertController, NavController, ViewController, Events, App } from 'ionic-angular';
import { Tabs } from '../tabs';
import { page1 } from '../page1';

@Injectable()
export class LoginService {
  userStatus: boolean;
  constructor(public events:Events, public alertController:AlertController, public navController: NavController, public viewController:ViewController, public app:App){}
  sendUserStatus(statusOfUser) {
    this.events.publish('login:Status', statusOfUser);
  }

  login(){
   //login successful
   this.sendUserStatus(true)
  }

  logout(){
   //logout successful
     this.sendUserStatus(false)
      }
    }

pageWithLink.ts

import { Component } from '@angular/core';
import { Events } from 'ionic-angular';

@Component({
  selector: 'pageWithLink',
  templateUrl: 'pageWithLink.html',
  providers: [LoginService]
})
export class pageWithLink {
      person: any;
      constructor(public events:Events){
         this.events.subscribe('login:Status', login => {
         this.person = login;
        })
      }
}

pageWithLink.html

<ion-header class="opaque">
   <ion-buttons end>
      <button ion-button icon-only *ngIf="person" (click)="signout()">
        <ion-icon name="log-out"></ion-icon>
      </button>
      <button ion-button icon-only *ngIf="!person" (click)="openModal()">
        <ion-icon name="log-in"></ion-icon>
      </button>
    </ion-buttons>
</ion-header>

【问题讨论】:

  • providers: [LoginService]你是否在所有链接页面中设置它?
  • @suraj 是 LoginService 已在所有链接页面中设置。
  • 更新了答案.. 您不应该尝试在可注入服务中使用 NavCOntroller

标签: angular events ionic2


【解决方案1】:

@suraj 拥有其中的大部分内容,这导致了其他一些修复调整,包括: 1) 将我的构造函数中的大部分内容酌情设为私有 2) 为我解决的问题是为每个页面添加一个登录检查,以提供一个开始状态,以防用户已经登录。

新的 loginService.ts

import { Injectable } from '@angular/core';
import { Events } from 'ionic-angular';
import { AlertController, Events, App } from 'ionic-angular';//don't use NavController or ViewController in Injectables!
import { Tabs } from '../tabs';
import { page1 } from '../page1';

@Injectable()
export class LoginService {
  userStatus: boolean;
  constructor(private events:Events, private alertController:AlertController,  private app:App){}
  sendUserStatus(statusOfUser) {
    this.events.publish('login:Status', statusOfUser);
  }

  login(){
   //login successful
   this.sendUserStatus(true)
  }

  logout(){
   //logout successful
     this.sendUserStatus(false)
      }
    }

新页面WithLink.ts

import { Component } from '@angular/core';
import { Events } from 'ionic-angular';

@Component({
  selector: 'pageWithLink',
  templateUrl: 'pageWithLink.html'//no provider for LoginService, that's all in app.module.ts!
})
export class pageWithLink {
      person: any;
      constructor(private events:Events){

  if(UserExists){//this is a condition stating the current login status
    this.person = true;
   }

     this.events.subscribe('login:Status', login => {
     this.person = login;
    })
  }
}

【讨论】:

    【解决方案2】:

    设置

    providers: [LoginService]app.module.ts 中的 ngModule 中。

    目前您已将 LoginService 设置为每个页面的提供程序。因此,为每个组件创建了一个新服务。要使您的活动LoginService 需要是单例的。

    @NgModule({
        //declarations,imports etc.
        providers:[LoginService]
    })
    

    并从所有其他页面中删除提供程序。这样,单个服务只会发布一个事件,并且每个页面都会选择该事件。

    没有导航控制器的提供者

    是因为您将 Navcontroller 注入到服务中。 查看this answer 了解说明

    【讨论】:

    • 我喜欢你的回答,这就是文档所说的,但是当我从其他页面获取 LoginService 提供程序时,每个页面都会给我以下错误:./Tabs 类选项卡中的错误 - 原因:否NavController 的提供者!
    • 能否将 app.module.ts 添加到问题中?
    • app.module.ts 添加。也许我没有在应用程序的其他地方正确实现 LoginService?
    • 导航控制器错误是另一个错误..可能是 Tabs.ts 中的问题
    • 不是很有帮助,因为您提出的解决方案会导致错误。你认为我们可以进一步研究一下吗? navCtrl 和 viewCtrl 是 LoginService 的一部分。由于某种原因,当 Service 被视为单例时,他们正在注册错误。 . .
    【解决方案3】:

    我认为您需要订阅LoginService 中的events,因此请通过更新“pageWithLink”进行检查,如下所示:

    import { Component } from '@angular/core';
    import { Events } from 'ionic-angular';
    
    @Component({
      selector: 'pageWithLink',
      templateUrl: 'pageWithLink.html',
      providers: [LoginService]
    })
    export class pageWithLink {
      person: any;
      constructor(private loginService: LoginService){
         this.loginService.events.subscribe('login:Status', login => {
           this.person = login;
         });
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-27
      • 2016-11-04
      • 2020-11-24
      相关资源
      最近更新 更多