ionic 的坑

一、ionic 页面跳转

  • Ionic的页面布局一般是一组tabs,也就是一组一级标题,就好像知乎APP的下面是5个tab组成的一个tabs。但是每个tabs下面的页面
  • ionic 的跳转方式有两种,一种是NavController,一种是ModalController。
  • 一般情况下,我们都用navController的方式进行跳转,
    因为ModalController跳转不支持返回按钮,需要你手动的添加返回事件
    constructor(public navCtrl: NavController              ) {
}
    goHome(){
      this.navCtrl.push(HomePage);//跳转到HomePage
}
  • 一般情况下,我们都是一个页面往下一个页面跳,但是我们有可能会出现一个页面里面,有多个下级页面,而且下级页面之前,还可以进行二级tab跳转。这个时候,就有一个坑默默的等待着你。
    这种场景就好像有多个二级tab。
  • navPush他实际上的像人叠人这样一直叠的,除非你是一级Tabs跳转,才会把页面堆栈清空。不然你就会发现,你的html一直在增加。正常的使用还没什么,顶多后面页面加载速度会变慢。但是如果再加上echarts作图,你第二次进入这个页面,就会发现,图表没有正常的呈现出来,原因并不是echarts出问题的,原因就是,你的dom重复了,每个div的id和class都一样。但是echarts根据ID或者Class获取dom元素的时候,获取的是被叠在下面的dom,自然你的图表就显示不出来了。
  • 或许有人不用echarts图表,觉得没问题。但是还会出现一个问题就是,你从tab1=>html1=>html2=>html1=>html2的时候,调用pop方法返回上一层,你会发现要返回4次才能回到tab1,这个体验,显然不是用户想到的效果。体验糟透了。
  • 解决方式也很简单,我们在两个二级tab之间跳转的时候,在navPush的时候,加个回调函数,把当前页面的堆栈给去除,就好像我上面有人叠下来的时候,在他下来的那一刻,我走开,这样他就在最下面了。自然就不会出现人叠人不断叠的程度了。

解决方法

方法一

this.navCtrl.popToRoot(); //直接返回根组件
我们直接跳转到tabs根页面,自然会把堆栈清除,但是在不返回的过程中,相互跳转,页面堆栈叠加依然存在。

方法二

  • push 后再删除之前页面即可。
this.navCtrl.push(Html1Page).then(() => {
  const startIndex = this.navCtrl.getActive().index - 1;
  this.navCtrl.remove(startIndex, 1);
});
this.navCtrl.push(Html2Page).then(() => {
  const startIndex = this.navCtrl.getActive().index - 1;
  this.navCtrl.remove(startIndex, 1);
});
  • 我们在二级tab之间跳转成功的时候,就把上一个页面的页面从页面堆栈中清除,这样自然就不会出现堆栈叠加的情况,我们调用pop返回上一层返回的就是root根页面了。

二、多线程处理

  • ionic在双向绑定和页面渲染的时候,是分开线程处理的。所以有时候会出现一种情况是你明明日志的正常打印,但是下面却获取不到dom元素或者dom的值。例如我img的地址是从数据库获取的,然后通过双向绑定绑定进去,打印日志看到dom是有元素的,但是获取该dom的长宽(图片的长宽)却为0.这其实就是他们分开线程处理的坑。这个时候,你可能就要做处理了。

解决方法

方法一

  • 递归判断该dom里面的值是否为空,否则从新获取(处理不好风险高,但是稳定,一定要加上定时中断条件,不然会出现无限递归)。
 getImgURL(){
         this.rest.getImageUrl().subscribe(i => {
                this.imgUrl = i;
                    if(this.imgUrl==null){
                          this.getImgURL();
                     }
         }
}

方法二

  • 做延迟函数获取该dom,一般在100毫秒以后就能正常获取数据,但是万一遇到机子处理慢,100毫秒以后还是有可能没处理完,依然为空(不能百分百解决问题)。
 getImgURL(){
         this.rest.getImageUrl().subscribe(i => {
                this.imgUrl = i;
                 setTimeOut(()=>{
                    console.log(this.imgUrl)      
                  },100)
         }
}

三、移动端不支持session

  • ionic一般做的是移动端网页,也就是手机、平板电脑端的页面,这些页面和浏览器端有一个地方需要注意的,就是默认不支持 cookie ,服务端 session 的使用是需要客户端在请求的时候,带有浏览器端的 sessionId ,这样才可以辨别该 session 的拥有者,而 sessionId 的存储自然是存在cookie上了。所以手机端不支持cookie的话,就只能自己手动传或者改用其他方式存储原本存储在 session 里的信息。
  • 用 session 还有一个问题就是,不支持分布式,故建议如果后期有可能需要架构升级或者原本架构就是分布式的,就不要使用session了。
  • 一般网上解决该问题的方式是后端在登录或者保存该用户信息的时候,生成一个token(不重复),然后把该 token 发送到移动端,让他使用本地的 storage 存储,storage是一个移动端常常使用的本地存储,该存储也可以用于浏览器。然后我们需要验证用户信息的时候,前端发送的请求上,带上该 token ,通过该token获取对应的用户信息便于后端验证该请求的合理性。

后端存储用户信息的方式也有两种:

  • 方法一

  • 缓存(cache) 我们可以使用缓存(cache)存储该信息,token为key,用户信息为value(这里建议把用户信息通过 JsonAPI 转换成 josn 字符串,一般key只可以为 String 类型),这样我们就可以通过前端传过来的 token 获取去缓存(cache)获取到对应的数据。但是缓存(cache)同样不支持分布式,如果有分布式需要,建议使用第二个方式。
  • 方法二

  • redis redis是一个把数据存储在内存用的key-value型数据库,当然,很多人用它当做一个缓存库使用。因为他是存储在内存上的,所以我们的操作数据的速度也非常快,每秒可以操作大约100W个数据。而且 redis 是一个独立部署的数据库,所以我们只要拥有对应的key,就可以获取到对应的数据,所以基本任何架构,都可以使用 redis 作为缓存存储使用。
  • 我们只要把前端传过来的 token 作为key去找 redis 拿数据,就可以了,而且效率非常高,而且 redis 也支持分布式,可以有效的防止单点问题(某服务器挂了或者某实例挂了导致程序不能正常提供服务)。
  • 当然,redis是需要独立部署的,如果在小型项目中,就建议直接使用cache最为方便。

注意:

  • 在ionic中storage的获取,也是多线程完成了,所以一定要获取到对应的token再做请求,不然会造成token为null导致程序异常。

你可能感兴趣的:(ionic 的坑)