美文网首页ionic3+我的ionic
【Appetite】ionic3实录(七)次页实现及分析解决问题

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

作者: IT晴天 | 来源:发表于2017-11-04 01:58 被阅读776次

    最近有点忙,好久没更新了,还好没人催稿,也没人想打我……

    这次我们要实现这个页面效果:


    image.png

    这个页面其实很简单的,唯一有点麻烦的是上面那个轮播图。

    现在开始实现这个页面,步骤如下:

    一、先创建数据

    src/app/assets/data目录创建dessert-slides.json文件并添加如下内容作为轮播图的数据源:

    {
      "success": "true",
      "result": [{
        "src": "../assets/imgs/foods/1.jpg"
      }, {
        "src": "../assets/imgs/foods/2.jpg"
      }, {
        "src": "../assets/imgs/foods/3.jpg"
      }, {
        "src": "../assets/imgs/foods/4.jpg"
      }]
    }
    

    同目录下创建dessert-list.json文件并添加如下内容作为甜点列表的数据源:

    {
      "success": "true",
      "result": [{
        "title": "DIPPED APRICOTS",
        "desc": "BY RENEE",
        "src": "../assets/imgs/foods/1.jpg"
      }, {
        "title": "DIPPED DESSERT",
        "desc": "BY AMY HINE",
        "src": "../assets/imgs/foods/2.jpg"
      }]
    }
    

    二、创建数据服务

    执行命令创建数据服务aboutProvider

    ionic g provider about
    

    打开生成的文件并添加如下两个方法:

      /**
       * 获取甜点轮播图片
       */
      getDessertSlides(){
        return this.commonProvider.get("../assets/data/dessert-slides.json", false);
      }
    
      /**
       * 获取甜点列表
       */
      getDessertList(){
        return this.commonProvider.get("../assets/data/dessert-list.json", false);
      }
    

    三、改造页面

    修改about.ts为:

    import { Component, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';
    import { NavController, Slides } from 'ionic-angular';
    import { AboutProvider } from '../../providers/about/about';
    
    declare let Swiper: any;
    
    @Component({
      selector: 'page-about',
      templateUrl: 'about.html'
    })
    export class AboutPage {
    
      vm: {
        dessertSlides: any[],    //轮播数据源
        dessertList: any[],    //甜点列表数据源
        selectedSegment: string    //segment选择对象
      } = {
        dessertSlides: [],
        dessertList: [],
        selectedSegment: 'one'
      };
      constructor(public navCtrl: NavController, private aboutProvider: AboutProvider, private cd: ChangeDetectorRef) {
      }
    
      ionViewDidLoad() {
        this.getDessertSlides();
        this.getDessertList();
      }
    
      /**
       * 获取甜点轮播图片
       */
      getDessertSlides(){
        return this.aboutProvider.getDessertSlides().then((rep: any) => {
          this.vm.dessertSlides = rep.result;
          this.cd.detectChanges();
          this.initSwiper();
          return rep;
        });
      }
    
      /**
       * 获取甜点列表
       */
      getDessertList(){
        return this.aboutProvider.getDessertList().then((rep: any)=>{
          this.vm.dessertList = rep.result;
          return rep;
        });
      }
    
      /**
       * 初始化Swiper
       */
      initSwiper() {
        new Swiper('.wheel .swiper-container', {
          slidesPerView: 2,
          initialSlide: 1,
          watchActiveIndex: true,
          centeredSlides: true,
          resizeReInit: true,
          keyboardControl: true,
          grabCursor: true
        });
      }
    }
    
    

    对用于绑定的对象,我一般把它们放在一个叫vm的对象下,便于肉眼区分是绑定对象还是普通变量,这样当看到带vm前缀的变量赋值时,就会想到要刷新页面视图的情况,从而可以做一些相关处理,或避免频繁刷新。

    代码应该比较容易理解吧?其中有没有留意到一个细节:initSwiper方法为什么放在获取数据之后?它放在其它地方可以吗?此外,它上面为什么会放个this.cd.detectChanges()这些合为问题一

    修改about.html为:

    <ion-header class="primary-bg" no-border>
      <ion-navbar>
        <ion-buttons start>
          <button ion-button icon-only color="light">
             <ion-icon name="md-add"></ion-icon>
          </button>
        </ion-buttons>
        <ion-title>
          RECIPE ARCHIVE
        </ion-title>
        <ion-buttons end>
          <button ion-button icon-only color="light">
              <ion-icon name="md-menu"></ion-icon>
          </button>
        </ion-buttons>
      </ion-navbar>
      <ion-toolbar>
        <ion-segment mode="md" [(ngModel)]="vm.selectedSegment">
          <ion-segment-button value="one">
            DESSERT
            <div class="bolder-sm"></div>
          </ion-segment-button>
          <ion-segment-button value="two">
            DRINKS
            <div class="bolder-sm"></div>
          </ion-segment-button>
          <ion-segment-button value="three">
            EINKORN
            <div class="bolder-sm"></div>
          </ion-segment-button>
          <ion-segment-button value="four">
            LIFESTYLE
            <div class="bolder-sm"></div>
          </ion-segment-button>
        </ion-segment>
      </ion-toolbar>
    </ion-header>
    <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 class="swiper-container">
          <div class="swiper-wrapper">
            <div class="swiper-slide" *ngFor="let item of vm.dessertSlides">
              <div class="slide-zoom">
                <img [src]="item.src" />
              </div>
            </div>
          </div>
        </div>  
        <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'">segment二</div>
      <div [hidden]="vm.selectedSegment != 'three'">segment三</div>
      <div [hidden]="vm.selectedSegment != 'four'">segment四</div>
    </ion-content>
    

    无论text-center还是padding-left等,用的都是ionic的指令,同样有没有留意到细节:为什么用[hidden],不用*ngIf或者ngSwitch?此为问题二

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

    修改about.scss为:

    .swiper-container {
        width: 100%;
        height: 150px;
        //实现上下红白色各半
        background: linear-gradient(to bottom, color($colors, primary) 50%, color($colors, light) 50%)
      }
      .swiper-wrapper {
        width: 100%;
        height: 100%;
      }
      .swiper-slide {
        text-align: center;
        height: 100%;
        width: 100%;
      }
      //非激活的图片缩小为0.9倍
      .swiper-slide img {
        display: block;
        width: auto;
        max-width: 100%;
        height: 100%;
        max-height: 100%;
        border: 2px solid #fff;
        position: relative; 
        //   box-shadow: 0px 2px 5px rgba(0, 0, 0, 1);
        -webkit-transition: 300ms;
        -moz-transition: 300ms;
        -ms-transition: 300ms;
        -o-transition: 300ms;
        transition: 300ms;
        -webkit-transform: scale(0.9);
        -moz-transform: scale(0.9);
        -ms-transform: scale(0.9);
        -o-transform: scale(0.9);
        transform: scale(0.9);
        -webkit-backface-visibility: hidden;
      }
      //激活的图片恢复为原来的大小
      .swiper-slide-active img {
        -webkit-transform: scale(1);
        -moz-transform: scale(1);
        -ms-transform: scale(1);
        -o-transform: scale(1);
        transform: scale(1);
        opacity: 1;
      }
      .swiper-slide .slide-zoom {
        height: 100%;
        padding: 10px 10px 0px;
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
      } 
    

    其中//的为重要注释,主要是为了实现中间大,两边小的效果。

    最后运行看下效果:

    运行效果图

    问题解释留到下篇再讲,要动动手调试下才能思考下原因。

    相关文章

      网友评论

      • dml1874:有图片资源吗?
        dml1874:@IT_晴天 那可以给我一份吗?我再去百度的和您的感觉就差太多了
        IT晴天:@dml1874 都是度娘的

      本文标题:【Appetite】ionic3实录(七)次页实现及分析解决问题

      本文链接:https://www.haomeiwen.com/subject/npqzpxtx.html