【问题标题】:Change selected Tab after CRUD operation - Ionic2CRUD 操作后更改选定的选项卡 - Ionic2
【发布时间】:2016-08-24 05:21:36
【问题描述】:

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

在创建新条目并将其存储到数据库后,我无法重新加载锻炼选项卡。我能够操纵 NavController 为其设置 root 以显示更新的数据,但它仅位于 Add Workout 选项卡下。 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);
}

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

【问题讨论】:

    标签: angular typescript ionic2


    【解决方案1】:

    您可以通过使用 observable

    来做到这一点

    编辑:我已经编辑了答案,因为您不需要使用 observable 来同步两个组件,而是需要使用 observable 才能在添加新项目后更改选定的选项卡.

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

    所以想法是使用 observable 来允许其中一个子组件(插入新项目的页面)告诉父组件(包含两个选项卡的页面)它应该更改选定的选项卡(在本例中为显示项目列表的页面)。

    标签服务

    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);更改选中的标签

    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; 的组件中获取它

    <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"));
    

    【讨论】:

    • 非常感谢。你是个传奇。 :D 这是非常有帮助和彻底的。我对这两个框架都很陌生。所以,我试图通过构建多个简单的应用程序来玩。我总是在重新同步数据时遇到问题。
    • 我不知道为什么,但是当我添加条目时,它给出了这个错误。 TypeError:Cannot read property 'next' of null at SyncService.updateListOfItems (sync.service.ts:18) at SafeSubscriber._next (add.ts:42) at SafeSubscriber.__tryOrUnsub (Subscriber.js:225) at SafeSubscriber.next ( Subscriber.js:174) 在 Subscriber._next (Subscriber.js:124) 在 Subscriber.next (Subscriber.js:88) 在 MapSubscriber._next (map.js:82) 在 MapSubscriber.Subscriber.next (Subscriber.js: 88) 在 XMLHttpRequest.onLoad (xhr_backend.js:68) 在 ZoneDelegate.invokeTask (zone.js:356)
    • 我真的很感激。我不明白,但 updateListOfItems() 似乎不起作用,因为当我尝试在另一个页面(deleteWorkout)中调用该方法时,它会做同样的事情。页面未加载,但数据已更新。
    • 以防万一,您是否在 App 组件中添加 providers: [... SyncService]
    • 这很有帮助。非常感谢您的参与。 :D
    猜你喜欢
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多