【问题标题】:Ionic 3 Angular 4 Native GoogleMaps Lifecycle Events: What's the REAL order?Ionic 3 Angular 4 Native GoogleMaps 生命周期事件:真正的顺序是什么?
【发布时间】:2018-02-27 06:05:07
【问题描述】:

我在试图弄清楚如何让事件以正确的顺序触发时遇到了问题。据我了解,顺序如下:

ionViewDidLoad -> ionViewWillEnter -> ionViewDidEnter -> ionViewWillLeave -> ionViewDidLeave

但我的问题是,构造函数在生命周期中去哪里了?那么platform.ready 呢?我在构造函数中有一些事件应该加载 Google Maps API,但由于某种原因,其他所有事件似乎都会在它们之前触发,尤其是当我使用 this.platform.ready().then() 时。

以下是相关代码:

app.component.ts

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { Http } from '@angular/http';
import { Storage } from '@ionic/storage';
import { TabsPage } from '../pages/tabs/tabs';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';


@Component({
  templateUrl: 'app.html'
})
export class CanalGuide {
  rootPage:any = TabsPage;
  public types;
  public places;

  constructor(public http: Http, public platform: Platform, public statusBar: StatusBar, public splashScreen: SplashScreen, public storage: Storage) {
      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();  
      this.readyTypes();
      this.readyPlaces();
      splashScreen.hide();
      });
    }

home.ts

   import { Component, ViewChild } from '@angular/core';
import { Platform, NavController } from 'ionic-angular';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/forkJoin';
import { Storage } from '@ionic/storage';

import {
 GoogleMaps,
 GoogleMap,
 GoogleMapsEvent,
 LatLng,
 MarkerOptions,
 Marker
} from '@ionic-native/google-maps';
import { DetailsPage } from '../details/details';
import { SettingsPage } from '../settings/settings';
import { SettingsService } from '../settings/settings.service';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
})
export class HomePage {
  @ViewChild('map') element;

  public types;
  public places;
  public landmarks;
  public launches;
  public structures;
  public docks;
  public landmarkArray: any[] = [];
  public launchArray: any[] = [];

  constructor(public navCtrl: NavController, public platform: Platform, public http: Http, private googleMaps: GoogleMaps, public storage: Storage) {}
    // Gets json file and prepares to create markers

    ionViewDidLoad(){
      this.storage.get('places').then(
        data => { 
          this.places = data;
          this.initMap(this.places); 
        },
        error => { console.log('Error:', error); }
      );
    }

  }

ionViewDidEnter(){
    if (this.landmarkArray.length < 1)
     return false
    else
      this.storage.get('types').then((data) => { 
       this.types = data;
       }).then(() => {
       this.storage.get('launches').then((data) => {
         this.launches = data;
         console.log(this.launches); // returns Array(0)
         if (this.types.types[3].enabled === false) 
             this.launches.launches.ForEach((launch) => {
               launch.setVisible(false);
             });
         else this.launches.launches.ForEach((launch) => {
               launch.setVisible(true);
             });
          });
       }).then(() => {
         this.storage.get('landmarks').then((data) => {
         this.landmarks = data;
         console.log(this.landmarks); // returns Array(0)
         if (this.types.types[4].enabled === false) 
             this.landmarks.landmarks.ForEach((landmark) => {
               landmark.setVisible(false);
             });
         else this.landmarks.landmarks.ForEach((landmark) => {
               landmark.setVisible(true);
             });
          });
       });
  }
}

谁能提供一些关于为什么我的ionViewDidEnterhome.ts 的构造函数之前触发的一些见解,以及我可以做些什么来确保它们以正确的顺序触发?

这是我在 ionic cordova run android 中运行此日志时的样子 没有解决方法:

main.js:338 undefined
main.js:339 undefined
vendor.js:117149 Ionic Native: deviceready event fired after 5760 ms
main.js:306 []
main.js:307 []

【问题讨论】:

  • 请简化您在这篇文章中工作的代码,因为它包含太多与您的问题无关的信息,请在您将控制台日志定位的地方添加评论问题。

标签: javascript angular ionic-framework


【解决方案1】:

所以构造函数首先触发,在 ionViewDidLoad 之前。

现在关于平台准备好进入 app.component 构造函数,这个事件告诉你什么时候可以使用本机功能,如果在浏览器中运行它会告诉你什么时候DOM 已准备就绪。

As stated in the official docs

platform.ready().then() 是您放置 GMaps 初始化代码的位置。

编辑 1

现在您已经添加了一些代码,并且您没有在 app.component.ts 中实例化谷歌地图库,而只是获取数据并存储它,有几件事修复。

platform.ready()

仅在 app.component.ts 中出现,因此在 home.ts 中,您可以直接访问 this.storage.get(...) 而无需将其包装在 platform.ready().then() 中,也可以在 ionViewDidEnter 中将其删除,这是导致一个问题,这就是为什么你会看到事情以奇怪的顺序发生。

这应该会给你一个稳定的数据流。

【讨论】:

  • 它不工作。 ionViewDidEnter 仍然在构造函数之前触发,至少根据控制台是这样。有什么我可以使用的解决方法吗?
  • 您是否删除了所有 platform.ready()?还要记住 storage.get 操作会解析一个承诺,所以如果你想检查事件的真实顺序,请在函数定义之后(而不是在承诺内)进行控制台日志。无论如何,请在修复代码时不断更新帖子中的代码。
  • 所有platform.ready()除了app.component.ts中的那个
  • 我能想到的最佳解决方法是添加一个条件,如果 landmarkArray 的长度小于 1,则停止 ionViewDidEnter 中的代码运行。
  • 继续更新帖子,你解决了吗?还是有问题?
猜你喜欢
  • 2019-06-17
  • 2018-05-02
  • 2012-10-08
  • 2018-01-28
  • 2018-07-10
  • 1970-01-01
  • 2018-10-07
  • 1970-01-01
相关资源
最近更新 更多