【Appetite】ionic3实录(七)次页实现及分析解决问题【下】

上一节提到几个问题,现在我们逐一来解释一下:

问题一:initSwiper方法为什么放在获取数据之后?它放在其它地方可以吗?此外,它上面为什么会放个this.cd.detectChanges()?

initSwiper() {
    new Swiper('.wheel .swiper-container', {
      slidesPerView: 2,
      initialSlide: 1,
      watchActiveIndex: true,
      centeredSlides: true,
      resizeReInit: true,
      keyboardControl: true,
      grabCursor: true
    });
  }

一般一些js插件,是依托dom的。我们观察initSwiper方法,第一个参数'.wheel .swiper-container'其实是个选择器,所以它也是依托dom操作的,此外,由于我们使用了数据绑定,this.vm.dessertSlides的值更新会影响到dom,所以应该在数据更新从而使得dom更新完成后再调用initSwiper方法。
angular的脏检测机制是基于一定条件和时间的,在给this.vm.dessertSlides赋值,dom还没更新完成就调用initSwiper方法不一定会获得想要结果的,所以在此之前调用手动检测方法this.cd.detectChanges()强制检测并刷新dom。

问题二:为什么用[hidden],不用*ngIf或者ngSwitch?

因为前者只是隐藏,而后两者是会移除。也就是说,前者只会初始化一次,而后两者每次显示都需要重新初始化,进一步说,若使用后两者方式,对于这里用到的swiper,它不是一个angular封装起来的组件,不会自动初始化,我们每次显示它时都需要显式调用一下initSwiper方法,这就有点繁琐还耗费性能。同理,有些组件要注意类似情况。这并不是说都不要用*ngIf,因为当页面元素太多时会容易导致界面卡顿,所以没用的多余元素应该移除,此时就用它。一句话说就是根据情况合理选择显示控制方法

问题三

标签内容能否换成注释掉的内容?

这是当然可以的,因为ion-slides组件组件最终也是生成

标签代码。

问题三的延伸:既然ion-slides已经是封装起来的控件了,我们用它不是可以省掉不少代码?

是的,在大多场景中可以直接用ion-slides,只是会有个别坑要解决,比如我们改动下ts和html文件。

ts中把initSwiper方法相关内容移除:

import { Component, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';
import { NavController, Slides, PopoverController } from 'ionic-angular';
import { AboutProvider } from '../../providers/about/about';
import { ChatPage } from '../contact/chat/chat';

declare let Swiper: any;

@Component({
  selector: 'page-about',
  templateUrl: 'about.html'
})
export class AboutPage {

  @ViewChild(Slides) slides: Slides;
  vm: {
    dessertSlides: any[] ,    //轮播数据源
    dessertList: any[],    //甜点列表数据源
    selectedSegment: string    //segment选择对象
  } = {
    dessertSlides: [],
    dessertList: [],
    selectedSegment: 'one'
  };

  constructor(public navCtrl: NavController, private aboutProvider: AboutProvider, private cd: ChangeDetectorRef, private popoverController: PopoverController) {
  }

  ionViewDidLoad() {
    this.getDessertSlides();
    this.getDessertList();
  }

  /**
   * 获取甜点轮播图片
   */
  getDessertSlides(){
    return this.aboutProvider.getDessertSlides().then((rep: any) => {
      this.vm.dessertSlides = rep.result;
      return rep;
    });
  }

  /**
   * 获取甜点列表
   */
  getDessertList(){
    return this.aboutProvider.getDessertList().then((rep: any)=>{
      this.vm.dessertList = rep.result;
      return rep;
    });
  }
  }
}

html里用ion-slides:


  
{{item.title}}

{{item.desc}}

{{item.title}}

{{item.desc}}

执行看下效果:


【Appetite】ionic3实录(七)次页实现及分析解决问题【下】_第1张图片
数据未正确应用

对比上一节的实际效果图,会发现这里只显示了两个图片,什么原因呢?是因为该组件在异步获取到数据this.vm.dessertSlides前已完成了初始化了,这样新数据其实没有应用到,为了处理这种情况,我们改造一下html,为ion-slides组件加上一段*ngIf="vm.dessertSlides && vm.dessertSlides.length>0"

    
      
        
      
       

这样当新数据有值且长度大于0时,才会显示ion-slides组件,进而内部进行初始化,此时运行看效果如下,只是此时有个比较突兀的2图向3图切换效果,有兴趣的可以试试:

【Appetite】ionic3实录(七)次页实现及分析解决问题【下】_第2张图片
数据正确应用

你可能感兴趣的:(【Appetite】ionic3实录(七)次页实现及分析解决问题【下】)