ionic3項目實戰(zhàn)教程 - 第10講 ionic3分類菜單設計(類似外賣)

注意幻件,干貨來了,相比前面幾講這一講就要難以消化多了蛔溃,請做好心理準備傲武。

因為在這之前,經(jīng)吵情唬看到有群友在求這種分類菜單的組建,今天我就為大家再造一個輪子 [微笑臉]态兴。

這一講主要包含以下幾個部分:

  • 1.效果圖
  • 2.布局思考
  • 3.具體代碼展示

1.效果圖

10-1.png

2.布局思考

  • 2.1.左右布局狠持,考慮用ion-grid,一個ion-row瞻润,兩個ion-col;

      <ion-grid>
        <ion-row>
           <ion-col>這里放菜單列表</ion-col>
           <ion-col>這里放商品列表</ion-col>
        </ion-row>
      </ion-grid>
    
  • 2.2.分類和商品列表需要滾動

      <ion-grid>
        <ion-row>
           <ion-col><ion-scroll>這里放菜單列表</ion-scroll><ion-col>
           <ion-col><ion-scroll>這里放商品列表</ion-scroll><ion-col>
        </ion-row>
      </ion-grid>
    
  • 2.3.左邊菜單使用ion-list,右邊商品列表使用我們之前封裝的組建ion-products喘垂;

3.具體代碼展示

這一講的所有改動都在/src/pages/contact文件夾中,相信通過前面的幾講绍撞,大家對ionic3已經(jīng)有了一個?初步的認識正勒,那么讀懂以下代碼應該不是難事。

以下分別是 contact.module.ts ,contact.ts, contact.html , contact.scss 的完整代碼:

這里用到了ion-products組建傻铣,需要在對應的module中導入依賴:

contact.module.ts

import { ComponentsModule } from './../../components/components.module';
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { ContactPage } from './contact';

@NgModule({
    declarations: [
        ContactPage,
    ],
    imports: [
        IonicPageModule.forChild(ContactPage),ComponentsModule
    ],
})
export class ContactPageModule { }

難讀懂的代碼都添加了注釋章贞。

contact.ts

import { AppGlobal, AppService } from './../../app/app.service';
import { Component, ViewChild } from '@angular/core';
import { NavController, IonicPage } from 'ionic-angular';

@IonicPage()
@Component({
  selector: 'page-contact',
  templateUrl: 'contact.html'
})
export class ContactPage {

  @ViewChild('scroll') scrollElement: any;
  @ViewChild('spinner') spinnerElement: any;

  categories: Array<any> = [];
  selectedMenuTarget: any;
  products: Array<any> = [];
  hasmore = true;

  islock = false;

  params = {
    favoritesId: 0,
    pageNo: 1
  }

  constructor(public navCtrl: NavController,
    public appService: AppService) {

  }

  ionViewDidLoad() {
    this.getCategories();
    this.addScrollEventListener();
  }

  addScrollEventListener() {
    this.scrollElement._scrollContent.nativeElement.onscroll = event => {
      if (this.spinnerElement) {
        //元素頂端到可見區(qū)域頂端的距離
        var top = this.spinnerElement.nativeElement.getBoundingClientRect().top;
        //可見區(qū)域高度
        var clientHeight = document.documentElement.clientHeight;
        if (top <= clientHeight) {
          console.log("ready loadmore...");
          this.doInfinite();
        }
      }
    }
  }

  // 獲取左側菜單
  getCategories() {
    this.appService.httpGet(AppGlobal.API.getCategories, { appTag: 'dress' }, rs => {
      console.debug(rs);
      this.categories = rs.data;
      //默認獲取第一個分類的商品列表
      this.params.favoritesId = this.categories[0].FavoritesId;
      this.getProducts();
    })
  }

  // 選中左側菜單
  itemClick(c, event) {

    var initSelected: any = document.getElementsByClassName('menuItem');
    if (initSelected[0].classList.contains("active")) {
      initSelected[0].classList.remove("active")
    }

    //移除上次選中菜單的樣式
    if (this.selectedMenuTarget) {
      this.selectedMenuTarget.classList.remove("active")
    }

    //修改本次選中菜單的樣式
    event.currentTarget.classList.add("active");

    //將本次選中的菜單記錄
    this.selectedMenuTarget = event.currentTarget;

    this.hasmore = true;

    this.params.favoritesId = c.FavoritesId;
    this.params.pageNo = 1;

    this.getProducts();
  }

  getProducts() {
    this.appService.httpGet(AppGlobal.API.getProducts, this.params, rs => {
      this.products = rs.data;
      this.params.pageNo += 1;
    })
  }

  doInfinite() {
    if (this.islock) {
      return;
    }
    if (this.hasmore == false) {
      return;
    }
    this.islock = true;
    this.appService.httpGet(AppGlobal.API.getProducts, this.params, d => {
      this.islock = false;
      if (d.data.length > 0) {
        this.products = this.products.concat(d.data);
        this.params.pageNo += 1;
      } else {
        this.hasmore = false;
        console.log("沒有數(shù)據(jù)啦!")
      }
    });
  }

  goDetails(item) {
    this.navCtrl.push('ProductDetailsPage', { item: item });
  }
}

這里說明下非洲,addScrollEventListener函數(shù)里主要實現(xiàn)的是自定義加載更多功能鸭限。

contact.html

<ion-header>
  <ion-navbar style="opacity: 0.8" no-border-bottom color="primary">
    <ion-title>優(yōu)惠精選</ion-title>
  </ion-navbar>
</ion-header>
<ion-content fullscreen>
  <ion-grid no-padding>
    <ion-row>
      <ion-col col-3 class="menus">
        <ion-scroll scrollY="true" style="height:100%">
          <ion-list no-lines>
            <ion-item button class="menuItem" *ngFor="let c of categories;let i=index" [ngClass]="{'active': i==0}" text-center (click)="itemClick(c,$event)">
              {{c.FavoritesTitle}} </ion-item>
          </ion-list>
        </ion-scroll>
      </ion-col>
      <ion-col class="items">
        <ion-scroll scrollY="true" #scroll style="height:100%">
          <ion-products [products]="products"></ion-products>
          <ion-row>
            <ion-col class="nodata" text-center *ngIf="!hasmore">
              沒有商品啦 ?(^?^*)
            </ion-col>
          </ion-row>
          <ion-row #spinner *ngIf="hasmore">
            <ion-col text-center>
              <ion-spinner></ion-spinner>
            </ion-col>
          </ion-row>
        </ion-scroll>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

contact.scss

  page-contact {
  background: #efefef;
  .menus {
    height: 100%;
    ion-scroll {
      background-color: #efefef;
    }
  }
  .items {
    height: 100%;
    ion-scroll {
      background-color: #fff;
    }
  }
  ion-grid {
    padding: 0px;
    margin: 0px;
    height: 100%;
    ion-row {
      padding: 0px;
      margin: 0px;
      height: 100%;
      ion-col {
        padding: 0px;
        margin: 0px;
      }
    }
  }
  ion-list {
    ion-item {
      background: #efefef;
    }
  }
  .product {
    .scroll-content {
      margin-bottom: 0px;
    }
  }
  .menus {
    .active {
      background: #fff;
    }
    ion-item {
      background: #efefef;
      ion-label {
        font-family: "黑體";
        font-size: 90%;
      }
    }
  }
}

如果有不理解的地方蜕径,歡迎大家在文章下方進行留言,也可通過文章下方的聯(lián)系方式聯(lián)系到我败京。

完兜喻!

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市赡麦,隨后出現(xiàn)的幾起案子朴皆,更是在濱河造成了極大的恐慌,老刑警劉巖泛粹,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遂铡,死亡現(xiàn)場離奇詭異,居然都是意外死亡戚扳,警方通過查閱死者的電腦和手機忧便,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來帽借,“玉大人珠增,你說我怎么就攤上這事】嘲” “怎么了蒂教?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長脆荷。 經(jīng)常有香客問我凝垛,道長,這世上最難降的妖魔是什么蜓谋? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任梦皮,我火速辦了婚禮,結果婚禮上桃焕,老公的妹妹穿的比我還像新娘剑肯。我一直安慰自己,他們只是感情好观堂,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布让网。 她就那樣靜靜地躺著,像睡著了一般师痕。 火紅的嫁衣襯著肌膚如雪溃睹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天胰坟,我揣著相機與錄音因篇,去河邊找鬼。 笑死,一個胖子當著我的面吹牛惜犀,可吹牛的內(nèi)容都是我干的铛碑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼虽界,長吁一口氣:“原來是場噩夢啊……” “哼汽烦!你這毒婦竟也來了?” 一聲冷哼從身側響起莉御,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤撇吞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后礁叔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牍颈,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年琅关,在試婚紗的時候發(fā)現(xiàn)自己被綠了煮岁。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡涣易,死狀恐怖画机,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情新症,我是刑警寧澤步氏,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站徒爹,受9級特大地震影響荚醒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜隆嗅,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一界阁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胖喳,春花似錦铺董、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坝锰。三九已至粹懒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間顷级,已是汗流浹背凫乖。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人帽芽。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓删掀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親导街。 傳聞我的和親對象是個殘疾皇子披泪,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容