如何在Ionic中的选项卡之间传递数据

时间:2017-03-10 02:38:20

标签: javascript typescript ionic-framework ionic2

我有一个包含3个标签的简单项目。当用户点击第一个标签上的项目上的按钮时,我需要该项目移动到第二个标签,反之亦然。 (当发生这种情况时,我还需要通知服务器)。有没有办法让我在“关于页面”选项卡中将项目对象传递给数组,反之亦然?

home.html的

<ion-header>
  <ion-toolbar>
    <ion-title>Home</ion-title>
    <ion-buttons end>
      <button ion-button icon-only color="royal" (click)="updateData()">
        <ion-icon name="refresh"></ion-icon>
      </button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-list>
    <ion-item-sliding *ngFor="let item of items">
      <ion-item>
        <ion-icon name="alert" *ngIf="!item.taken" item-left></ion-icon>
        <ion-icon name="checkmark-circle-outline" *ngIf="item.taken" item-left></ion-icon>
        <h2><b>{{item.title}}</b></h2>
        <h3>{{item.name}} | {{item.number}}</h3>
        <h3 style="white-space: normal;"><b>Details:</b> {{item.text}}</h3>
      </ion-item>
      <ion-item-options side="left">
        <button ion-button color="primary" (click)="smsPressed(item)">
          <ion-icon name="text"></ion-icon>
          Text
        </button>
        <button ion-button color="secondary" (click)="phonePressed(item)">
          <ion-icon name="call"></ion-icon>
          Call
        </button>
      </ion-item-options>
      <ion-item-options side="right">
        <button ion-button color="primary" *ngIf="item.taken" (click)="responderPressed(item)">
          <ion-icon name="person"></ion-icon>
          Responder
        </button>
        <button ion-button color="primary" *ngIf="!item.taken" (click)="takecallPressed(item)">
          <ion-icon name="navigate"></ion-icon>
          Take Call
        </button>
      </ion-item-options>
    </ion-item-sliding>
  </ion-list>

  <ion-fab right bottom>
    <button ion-fab color="light" (click)="addItem()"><ion-icon name="add"></ion-icon></button>
  </ion-fab>
</ion-content>

home.ts

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

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  items: any[];

  constructor(public navCtrl: NavController, public alertCtrl: AlertController) {
    this.items = []
      this.items.push({
        title: "Title",
        text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pretium quam at est porta fringilla.",
        name: "Sam",
        number: "(555) 555-5555",
        taken: true,
        responder: {
          name: "Bob",
          phone: "(666) 666-6666"
        }
      })
      this.items.push({
        title: "Stuff",
        text: "Take Now",
        name: "Sam",
        number: "(555) 555-5555",
        taken: false,
        responder: {}
      })

  }

  buttonPressed(item){
    alert(item.title)
  }

  smsPressed(item){alert(item.number)}

  phonePressed(item){alert(item.number)}

  responderPressed(item){alert(item.responder.name)}

  takecallPressed(item){alert(item.taken)}

  updateData(){
    this.items.unshift({
      title: "Added",
      text: "Take Now",
      name: "Sam",
      number: "(555) 555-5555",
      taken: false,
      responder: {}
    })
  }

  addItem(){
    let prompt = this.alertCtrl.create({
      title: 'Add Call',
      message: "Enter the details for the call you want to add",
      inputs: [
        { name: 'title',  placeholder: 'Title'},
        { name: 'text',  placeholder: 'Details'},
        { name: 'name',  placeholder: 'Name'},
        { name: 'number',  placeholder: 'Number'},
      ],
      buttons: [
        { text: 'Cancel',handler: data => {}},
        { text: 'Save',handler: data => {
            this.items.unshift({
              title: data.title,text: data.text,
              name: data.name,number: data.number,
              taken: false,responder: {}
            })
          }
        }
      ]
    });
    prompt.present();
  }
}

tabs.html

<ion-tabs>
      <ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
      <ion-tab [root]="tab2Root" tabTitle="Current" tabIcon="alarm"></ion-tab>
      <ion-tab [root]="tab3Root" tabTitle="Account" tabIcon="contacts"></ion-tab>
</ion-tabs>

tabs.ts

import { Component } from '@angular/core';
import { HomePage } from '../home/home';
import { AboutPage } from '../about/about';
import { ContactPage } from '../contact/contact';

@Component({
  templateUrl: 'tabs.html'
})
export class TabsPage {
  // this tells the tabs component which Pages
  // should be each tab's root Page
  tab1Root: any = HomePage;
  tab2Root: any = AboutPage;
  tab3Root: any = ContactPage;

  constructor() {

  }
}

3 个答案:

答案 0 :(得分:7)

有几种方法可以实现这一目标。

    在传递数据时,
  1. Events将是正确的选择 不同页面之间。

      

    Events是一个发布 - 订阅样式事件系统,用于发送和发送   响应您应用中的应用级事件。

    使用

    创建活动
    constructor(public events: Events) {}
    function sendData(data) {
      events.publish('data:created', data);
    }
    

    使用

    订阅

    events.subscribe('data:created', (data) => { console.log( data); });

    1. 使用共享服务

      constructor(public shared: Share) {} pushData(data){ this.shared.items.push(data); }

      items

    2. 全局注入服务时,您可以使用this.shared.items访问其他组件中的app.module.ts
      1. 另一种选择是使用segments代替tabs。这取决于用例。对于简单的应用程序,这将是更好的解决方案。您可以从documentation
      2. 了解更多信息

        修改

        我避免将数据存储在数据库中,因为它不是一种有效的方法。但是这种方法可能有用例。

答案 1 :(得分:0)

LocalStorage - 这可能是您解决问题的方法之一。

您可以使用 -

在1个标签页中执行特定操作后,将必要的数据存储在localStorage中
let data = {"demo": "demo"};
localStorage.setItem('myData',JSON.stringify(data));

现在,在另一个选项卡中,您可以使用离子生命周期甚至ionViewWillEnter(),只要输入视图就会执行该生命周期,这样数据就会被刷新。您可以在此处访问localStorage中存储的数据,如下所示:

ionViewWillEnter(){
    let data = JSON.parse(localStorage.getItem('myData'));
    console.log("Did data load? : ",data);
}

注意:在JSON.stringify()存储和检索时,您需要使用JSON.parse()localStorage,因为您只能在其中存储字符串。

答案 2 :(得分:0)

我知道,旧线程和Observables / Events是做到这一点的好方法,

但是在Ionic中,选项卡是每个选项卡的另一个离子路由器出口。因此,您已经有ActivatedRoute。您可能会认为,选项卡组件中的ActivatedRoute仅用于该特定的离子路由器出口,并且不会包含tabs.ts所具有的相同数据,但是您可以访问父级ActivatedRoute。

这是解析器存储其解析数据的地方。

在您的标签中。ts只是填充此值(使用解析器或离子刷新器或其他方式)

this.activatedRoute.snapshot.data['yourData'];

在每个选项卡组件中,您都可以通过以下方式访问它:

this.activatedRoute.snapshot.parent.data['yourData'];

别忘了在构造函数中注入ActivatedRoute对象。

另外,请注意,这是用于离子4/5的解决方案,我不知道它是否适用于3和更早版本。