在渲染“页面”之前获取数据异步

Posted

技术标签:

【中文标题】在渲染“页面”之前获取数据异步【英文标题】:Get data async before a `Page` gets rendered 【发布时间】:2016-08-02 19:47:01 【问题描述】:

在呈现Page 之前获取数据异步的正确方法是什么?

Angular2 据我所知建议使用 @CanActivate 装饰器。遗憾的是,这不适用于 Ionic2,至少不适用于我和 others

显然Ionic2 使用了@CanActivate 装饰器see 但它没有记录,我无法弄清楚它到底做了什么。

尽管如此,this guy 指出,由于离子缓存,无论如何都应该使用Ionics View States。他的例子是这样的:

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

看起来他希望 Ionic 考虑返回的承诺,但是 quick glance 一个 Ionics 消息来源显示(至少我认为是这样)返回的值被忽略了。因此,不能保证在页面呈现之前 会解决承诺。这是带有 onPage* 的 example 以及它没有按需要/预期执行的原因。

所以我迷路了,如何完成这个简单的任务?

在第一个链接中,建议在导航到页面之前先解析数据,这会增加被调用者知道页面需要哪些数据的负担。在我看来,这不是一个选择。

*编辑:添加反例

【问题讨论】:

【参考方案1】:

对于在使用 Ionic 2 时限制页面访问的任何人来说,Ionic 推荐的生命周期事件似乎是ionViewCanEnter

来自文档:

ionViewCanEnter 在视图进入之前运行。这可以用作经过身份验证的视图中的一种“守卫”,您需要在视图进入之前检查权限。

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

【讨论】:

很好,我正在“在 *** 上爬取关于在使用 Ionic 2 时限制页面访问”:) 这是正确答案,应该排名更高......我终于明白了,这是我开始工作的一个笨蛋 - embed.plnkr.co/B8XPvV Angular 有一种方法可以将canActivate 应用于整个路由和相关的子路由。如果有办法将此保护应用于模块内的所有页面,它将节省大量散布在各处的ionViewCanEnter 代码。【参考方案2】:

我不确定这是否是官方的方式,但我在这种情况下使用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() 方法。

你可以找到working plunker here(使用 beta.9)

【讨论】:

这是迄今为止我见过的最好的“解决方法”。非常感谢 很高兴我能帮上忙 :) 我不知道为什么,但是无论我使用什么解决方案,视图都会在异步位之前加载..【参考方案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;
        
    

【讨论】:

以上是关于在渲染“页面”之前获取数据异步的主要内容,如果未能解决你的问题,请参考以下文章

nuxt.js中asyncData 方法能够在渲染组件之前异步获取数据

嵌套组件页面渲染完了还请求不到数据

React native - 在渲染应用程序组件之前从异步存储中获取数据

asyncData异步数据

Vue / Router:如何在渲染页面内容之前正确获取数据?

vue先加载数据再渲染