首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Appetite】ionic3实录(七)次页实现及分析解决问题【下】

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

作者头像
IT晴天
发布2018-08-20 10:28:03
1.4K0
发布2018-08-20 10:28:03
举报
文章被收录于专栏:ionic3+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,因为当页面元素太多时会容易导致界面卡顿,所以没用的多余元素应该移除,此时就用它。一句话说就是根据情况合理选择显示控制方法

问题三:<div class="swiper-container">标签内容能否换成注释掉的<ion-slides>内容?

这是当然可以的,因为ion-slides组件组件最终也是生成<div class="swiper-container">标签代码。

问题三的延伸:既然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:

<ion-content>
  <div [hidden]="vm.selectedSegment != 'one'" class="wheel">
     <ion-slides centeredSlides="true" slidesPerView="2" initialSlide="1" zoom="false" >
      <ion-slide *ngFor="let item of vm.dessertSlides">
        <img [src]="item.src" />
      </ion-slide>
    </ion-slides>     
    <div text-center *ngFor="let item of vm.dessertList" padding-left padding-right>
      <h5><strong>{{item.title}}</strong></h5>
      <p>{{item.desc}}</p>
      <img [src]="item.src" style="height: 140px; width: 100%;" />
    </div>
  </div>
  <div [hidden]="vm.selectedSegment !='two'" >
    <div text-center *ngFor="let item of dessertList" >
      <h5>{{item.title}}</h5>
      <p>{{item.desc}}</p>
      <img [src]="item.src" style="height: 140px; width: 100%;" />
    </div>
  </div>
  <div [hidden]="vm.selectedSegment != 'three'">
    三
  </div>
  <div [hidden]="vm.selectedSegment != 'four'">
    四
  </div>
</ion-content>

执行看下效果:

数据未正确应用

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

    <ion-slides centeredSlides="true" slidesPerView="2" initialSlide="1" zoom="false"  *ngIf="vm.dessertSlides && vm.dessertSlides.length>0">
      <ion-slide *ngFor="let item of vm.dessertSlides">
        <img [src]="item.src" />
      </ion-slide>
    </ion-slides>   

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

数据正确应用

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.11.07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档