Подтвердить что ты не робот

Получить данные async перед тем, как "Страница" будет отображаться

Каков правильный способ получения данных async до того, как Page получит визуализацию?

Angular2 предлагает декор @CanActivate, насколько я понимаю. К сожалению, это не работает с Ionic2, по крайней мере, не для меня и для других

По-видимому, Ionic2 делает что-то с декоратором @CanActivate, см. Но он не документирован, и я не могу понять, что именно он делает.

Тем не менее этот парень указывает, что следует использовать Ionics View States, в любом случае, из-за кеширования ионов. Его пример выглядит следующим образом:

  onPageWillEnter() { 
      return this._service.getComments().then(data => this.comments = data);
  }

Похоже, он ожидает, что Ионн рассмотрит возвращенное обещание, но быстрый взгляд источники Ionics показывают (по крайней мере, я так думаю) что возвращаемое значение игнорируется. Следовательно, нет гарантии, что обещание будет устранено до того, как страница будет отображена. Вот пример с onPage * и как он не выполняется по мере необходимости/ожидаемого.

Итак, я потерялся, как достичь этой простой задачи?

В первой ссылке было предложено разрешить данные перед тем, как перейти на страницу, что обременяет знание, какие данные необходимы для страницы на вызываемом абоненте. На мой взгляд, это не вариант.

* edit: добавлен отрицательный пример

4b9b3361

Ответ 1

Я не уверен, что это официальный способ сделать это, но я использую компонент Loading для ситуаций, подобных этому. Вы можете найти дополнительную информацию в Ionic API Docs.

Файл .ts будет выглядеть следующим образом:

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

@Component({
  templateUrl:"page1.html"
})
export class Page1 {
  // Loading component
  loading : any;
  // Information to obtain from server
  comments: string = '';

  constructor(nav: NavController) {
    this.nav = nav;
  }

  onPageWillEnter() {
    // Starts the process 
    this.showLoading();
  }

  private showLoading() {
    this.loading = Loading.create({
      content: "Please wait..."
    });
    // Show the loading page
    this.nav.present(this.loading);
    // Get the Async information 
    this.getAsyncData();
  }

  private getAsyncData() {

    // this simulates an async method like
    // this._service.getComments().then((data) => { 
    //     this.comments = data);
    //     this.hideLoading();
    // });

    setTimeout(() => {
      // This would be the part of the code inside the => {...}
      this.comments = "Data retrieved from server";
      // Hide the loading page
      this.hideLoading();
    }, 5000);
  }

  private hideLoading(){
    // Hide the loading component
    this.loading.dismiss();
  }
}

Код очень прост, поэтому он не нуждается в дополнительных деталях, идея состоит в том, чтобы определить Loading, чтобы мы могли его показать, а затем попытаемся получить информацию, и как только мы получим эти данные, мы можем скрыть его, вызвав метод this.loading.dismiss().

Здесь вы можете найти рабочий плункер (используя бета-версию 9)

Ответ 2

Для тех, кто сканирует Stackoverflow об ограничении доступа к страницам при использовании Ionic 2, похоже, что рекомендуемое для Ionic событие жизненного цикла - ionViewCanEnter.

Из документов:

ionViewCanEnter Запускается до того, как может войти вид. Это может использоваться как своего рода "защита" в аутентифицированных представлениях, где вам нужно проверить разрешения до того, как представление может войти.

http://ionicframework.com/docs/v2/api/navigation/NavController/

Ответ 3

Если вы переходите только к этой странице из одного места, вы не могли бы просто загрузить данные перед навигацией и использовать NavParams для передачи данных?

Я использую эту структуру для страницы профиля, с определенной страницы индекса, которую я нажимаю на пользователя, а затем извлекаю его профиль перед посещением его профиля. Вы можете показать приятный Loading, пока это происходит.

let self=this;
this.profileSvc.getProfile(id)
.then(profile => {
    self.nav.push(Profile, {profile:profile});
});

Теперь на странице профиля вы можете использовать NavParams для инициализации своей страницы.

export class Profile {
    profile:any;
    constructor(private params:NavParams) {
        if(params.get('profile')) {
            this.profile = params.get('profile');
        } else {
            this.profile = this.me;
        }
    }