CRUD 操作后更改选定的选项卡 - Ionic2

Change selected Tab after CRUD operation - Ionic2

该应用程序是一个简单的锻炼输入工具。它对 CRUD 操作进行基本 API 调用。 App Display

创建新条目并将其存储到数据库后,我无法重新加载锻炼选项卡。我能够操纵 NavController 为其设置 root 以显示更新的数据,但它仅在“添加锻炼”选项卡下。 Workouts updated in Add Workout tab 当我返回“锻炼”选项卡时。它将结果显示为附加的第一张图像。

我想这是因为构造函数和 NgOnInit 只初始化了一次。我该如何解决这个问题?

这是锻炼选项卡的代码。

export class WorkoutPage {
  navCtrl;
  workoutService;
  workouts;

static get parameters() {
    return [NavController, WorkoutService];
}

constructor(navCtrl, workoutService) {
  this.navCtrl = navCtrl;
  this.workoutService = workoutService;
  this.workoutService.getWorkouts().subscribe(workouts => {
    this.workouts = workouts;
  })
}

ngOnInit() {
  this.workoutService.getWorkouts().subscribe(workouts => {
    this.workouts = workouts;
  })
}

workoutSelected(event, workout) {
  this.navCtrl.push(WorkoutdetailPage, {
      workout: workout
  })
}
}  

这就是我在将新条目添加到数据库后执行 setRoot 的方式。

onSubmit() {
  var workout = {
    title: this.title,
    note: this.note,
    type: this.type
   }

  this.workoutService.addWorkout(workout)
    .subscribe(data => {
        this.result = data;
    }, err => console.log(err),
    () => console.log("Workout added"));

    this.navCtrl.setRoot(WorkoutPage);
}

我真的需要一种方法来刷新锻炼页面上的数据。非常感谢您的帮助。

您可以使用 observable

EDIT:我已经编辑了答案,因为您不需要使用可观察对象来同步两个组件,您需要使用可观察对象来更改选定的选项卡一次新项目已添加。

由于每个选项卡都有自己的导航历史记录,您不能只在一个选项卡内使用 setRoot() 方法,因为那样会将新页面设置为 该选项卡的根目录 而不是将用户返回到另一个选项卡。

因此,我们的想法是使用 observable 来允许子组件之一(插入新项目的页面)告诉父组件(包含两者的页面)选项卡)它应该更改选定的选项卡(在这种情况下,显示项目列表的页面)。

TabService

import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class TabService { 

  private tabChangeObserver: any;
  public tabChange: any;

  constructor(){
    this.tabChangeObserver = null;
    this.tabChange = Observable.create(observer => {
        this.tabChangeObserver = observer;
    });
  }

  public changeTabInContainerPage(index: number) {
    this.tabChangeObserver.next(index);
  }
}

所以基本上 TabService 只创建一个 Observable 以允许选项卡容器订阅它,并且还声明将从子页面调用的 changeTabInContainerPage() 方法。

TabsPage中,我们只订阅服务,然后我们用this.tabRef.select(index);

更改选中的tab
import { Component, ViewChild } from "@angular/core";
import { Page1 } from './page1.ts';
import { Page2 } from './page2.ts';
import { TabService } from 'tabService.ts'; 

@Component({
  templateUrl: 'tabs.html'
})
export class TabsPage {
  @ViewChild('myTabs') tabRef: Tabs;

  tab1Root: any = Page1;
  tab2Root: any = Page2;

  constructor(private tabService: TabService){
    this.tabService.tabChange.subscribe((index) => {
      this.tabRef.select(index);
    });
  }
}

请注意,我们通过在 ion-tabs 元素中添加 #myTabs 来获取对 Tabs 实例的引用,并且我们使用 @ViewChild('myTabs') tabRef: Tabs;[=23 从组件中获取它=]

<ion-tabs #myTabs>
  <ion-tab [root]="tab1Root" tabTitle="Tab 1"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="Tab 2"></ion-tab>
</ion-tabs>

然后,唯一要做的就是在将新项目添加到列表时调用该方法:

    // Add the new item
    this.workoutService.addWorkout(this.newWorkout)
        .subscribe(
          (data) => {

            // Reset the form
            this.newWorkout = '';

            // Change the selected tab
            this.tabService.changeTabInContainerPage(0);
          }, 
          (err) => console.log(err),
          () => console.log("Workout added"));