【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,因为当页面元素太多时会容易导致界面卡顿,所以没用的多余元素应该移除,此时就用它。一句话说就是根据情况合理选择显示控制方法

问题三:<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图切换效果,有兴趣的可以试试:

数据正确应用

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小狼的世界

VIM的常用操作

作为Linux开发的必不可少的工具,能够将Vi的功效发挥到极致,必然能够提高我们的工作效率,下面是一些Vi的使用技巧。

14330
来自专栏为数不多的Android技巧

Android Studio你不知道的快捷键(三)

有没有这样的场景:你在Android Studio打开了一个图片文件(或者别的文件),想在资源浏览器里面查看这图片;在Eclipse里面我想大部分的人是Alt ...

13910
来自专栏ytkah

如何将文章列表用<li>分两列显示

  我们平时用ul或ol标签来罗列文章列表时默认是一列,为了美观起见,想把它们两列显示要如何操作呢?怎么用css定义它们?   其实相对比较简单,用几行css样...

351110
来自专栏ASP.NET MVC5 后台权限管理系统

Fastreport.net 如何在开发MVC应用程序时使用报表

26740
来自专栏挖坑填坑

angular页面打印局部功能实现方法思考

在页面显示的时候是分页现实的,当前页面只有10条数据,但是打印需要打印完整的100条数据。 并且在当前页面包含了表格之外的标题,菜单等其他元素。 后天api...

12420
来自专栏Objective-C

iOS-UITableView 之 重写 loadView 导致程序崩溃

29160
来自专栏前端杂谈

使用vue开发项目需要注意的问题和可能踩到的坑

最近,在公司给一些刚刚使用vue进行开发的同学做了一次分享, 其中包括一些vue开发中需要注意的点, 以及一些可能会踩到的坑.具体内容如下:

12920
来自专栏用户2442861的专栏

无插件Vim编程技巧

相信大家看过《简明Vim教程》也玩了《Vim大冒险》的游戏了,相信大家对Vim都有一个好的入门了。我在这里把我日常用Vim编程的一些技巧列出来给大家看看,希望...

13420
来自专栏木头编程 - moTzxx

小程序 动态修改二维数组 示例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

17810
来自专栏崔庆才的专栏

Bash 脚本 set 命令教程

17950

扫码关注云+社区

领取腾讯云代金券