博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(页面滑动)ionic2-super-tabs插件的使用及注意地方
阅读量:6278 次
发布时间:2019-06-22

本文共 8096 字,大约阅读时间需要 26 分钟。

hot3.png

简陋的自定义组件滑动菜单效果实现(slides + slides)

最终效果如下:

简单的代码如下:

slide-tab-demo
{
{slide.name}}

ts代码:

import { Component, ViewChild } from '@angular/core';import { IonicPage, NavController, NavParams, Slides, Tabs } from 'ionic-angular';@Component({  selector: 'page-slide-tab-demo',  templateUrl: 'slide-tab-demo.html',})export class SlideTabDemoPage {  @ViewChild("slidesRef")  slidesRef: Slides;  @ViewChild("tabsRef")  tabsRef: Tabs;  slides: any[] = [];  currentTabId = "tab1";  tabs: any[] = [];  navSelectedIndex = 0;  constructor(    public navCtrl: NavController,    public alert: Alert,    public navParams: NavParams  ) {    this.slides = [{      name: '头条新闻'    }, {      name: '娱乐新闻'    },    {      name: '体育新闻'    }];    this.tabs = [{      _name: "头条",      num: 99    }, {      _name: "娱乐",      num: 0    }, {      _name: "热点",      num: 0    }, {      _name: "体育",      num: 4    }, {      _name: "财经",      num: 0    }, {      _name: "汽车",      num: 0    }, {      _name: "时尚",      num: 0    }];  }  slideClick(slideIndex) {    this.slidesRef.slideTo(slideIndex);  }  slideChanged($event) {    let currentIndex = this.slidesRef.getActiveIndex();    // this.alert.showAlert('sss');    this.navSelectedIndex = currentIndex;  }}

简陋版slides+slides总结:能应付一般业务需求不繁琐的页面显示,但体验不好

一:滚动条问题,由于ion-slides的高度是以子页面ion-slide的高度为最终同一高度,当页面间高度不一致的时候,会导致高度矮的页面出现一大段空白背景,如果业务场景需要slide上拉刷新的时候,就要把空白背景拉完才会触发刷新效果。

解决办法:通过自定义指令获取屏幕高度减去上下tab栏来固定ion-slides的高度,但这时候会出现双滚动条,content一个,slides一个可能会出现其他的坑。

二:首页点击需要跳到指定的页面不好控制,在开发过程中,会出现点击滑动失效的问题,原因不明。

 

ionic2-super-tabs插件的使用

既然官方不提供,肯定有各路大神提供牛逼的组件,这个组件封装涵盖了angular的大部分核心思想及ionic页面生命周期,大神都说能写出来这个,其他组件随便封装。

基本使用上边都有说明,简单说一下

1、哪里用到super-tabs,就要在对应的module下引用

SuperTabsModule.forRoot()

2、页面充分用到懒加载[root]="xxPage",这里的Page就无需再次在根模块declarations、entryComponents、exports再次声明,直接在ts里xxpage : string = 'XXPage',字符串导入即可

3、进入子页面都会默认把前后一个页面同时渲染,有点类似ngIf(如6个子页面,进入第一个页面会渲染第一第二个页面,进入第二个页面会渲染第二第三个页面),所以如果请求数据太多要注重优化

4、父子页面的继承,只有第一次进入页面this的指向才是父页面,其余的操作都是指向每一个子页面,下面坑继续说

ionic2-super-tabs插件的注意地方

目录结构                               业务场景(三个super-tabs同时存在task页面上)

由于一开始做这种需求是通过文首用的slides+slides的方法,很多都是通过this去全局控制每一个页面的状态,类型等,这个时候的this是非常好用的。但是用了super-tabs这个组件后this就失去了原来的光环。

原因剖析:super-tabs采用的是子页面加载,尽管这很好的解决首页跳转页面的问题,但随即而来的继承会导致this失效,每个task.ts除了第一次渲染this是指向TaskPage外,其余的任何操作都是指向当前的子页面,所以TaskPage的生命周期里面的操作也会到每个子页面上操作,这样就会重复做相同的事情。

解决办法:在ionViewDidLoad完成第一次加载所需的接口,在每个子页面都重写一个ionViewDidLoad,ionViewWillEnter周期覆盖父类的声明周期,这样就很好的规避一样操作重复做,其余的功能性操作如点击刷新列表等写在ionViewDidEnter,最好写在每个子页面。父类private的属性和方法,子类也能继承

task.html

task.ts (三个生命周期,大量运用到eventproxy神器)

注:  this.navCtrl.getActiveChildNavs()用于获取是否有子类,无则undefined

         self.navCtrl.getActiveChildNav().getActiveTab().getViews();获取子页面实例对象ViewController

ionViewDidLoad() {        let self = this;        let instance;        /*tslint:disable*/        console.log('task----load')        /*tslint:enable*/        //详情页返回删除数据        // 监听详情完成操作事件        // 如果要根据详情操作动态删除记录,详情操作结束派发事件‘finish_operate_in_details’        try {            window['epInstance'].unbind('finish_operate_in_details').bind('finish_operate_in_details', (option) => {                // 监听从详情进入任务父类页面                window['epInstance'].unbind('main_task_page_didenter').bind('main_task_page_didenter', (data) => {                    // 获取子页面实例对象                    let views = self.navCtrl.getActiveChildNav().getActiveTab().getViews();                    if (views && views[0]) {                        instance = views[0]['instance'];                    }                    let taskData = instance.taskArrTemp[option.segment][option.saveStatu] || [];                    window['epInstance']['emit']('refresh_task_node_count', option.segment);                    // 动态删除任务记录                    taskData.forEach((item, index) => {                        if (item.id === option.taskId || item.taskId === option.taskId) {                            taskData.splice(index, 1);                        }                    });                });            });        } catch (e) {        }        // 叫我刷新我就刷新        try {            window['epInstance'].unbind('refresh_main_task_page').bind('refresh_main_task_page', (data) => {                let childInst = this.getChildPageInstnce();                if (childInst) {                    childInst.selectInterface(false);                }            });            //刷新节点数量            window['epInstance'].unbind('refresh_task_node_count').bind('refresh_task_node_count', (segment) => {                this.getAppNodeTypeCount(segment);            });        } catch (e) {            /*tslint:disable*/            /*tslint:enable*/        }    }    ionViewWillEnter() {        //今日提醒        this._todayTask = this.global.getValue('todayTask');        // 详情页页面离开生命周期(ionViewDidLeave)派发leave_from_details事件。配合finish_operate_in_details事件控制动态删除记录        window['epInstance'].unbind('leave_from_details').bind('leave_from_details', (data) => {            window['epInstance']['emit']('main_task_page_didenter', null);        });        // 由于pageTaskItem已经继承了eventproxy实例,在pageTask页面再次继承该实例会被pageTaskItem的实例覆盖,所以要在全局定义变量        window['epInstance'].unbind('toggle_call_panel').bind('toggle_call_panel', (data) => {            if (data) {                this.toggleCallPanel = true;                Object.assign(this.taskPhone, data);            } else {                this.toggleCallPanel = false;            }        });        // 导航        window['epInstance'].unbind('toggle_nav_panel').bind('toggle_nav_panel', (data) => {            if (data) {                this.toggleNavPanel = true;                Object.assign(this.taskNav, data);            } else {                this.toggleNavPanel = false;            }        });        let activePages = this.navCtrl.getActiveChildNavs();        // 控制子类不要重复执行代码        if (this.global.getValue('segment') && activePages && activePages.length) {            let intervalTime = 10;            // 首次进入渲染较慢,延迟跳转,临时使用解决方案            // https://github.com/ionic-team/ionic/issues/12401 等待ionic-angular版本更新解决问题            if (this.firstEntry) {                //首次进入控制                intervalTime = 400;            }            // 外面定时器是保证先渲染好页面再转换任务状态,渲染新的supertabs            setTimeout(() => {                this.segment = this.global.getValue('segment');                this._tabIndex = this.global.getValue('tabIndex');                // 这里的定时器是因为ngIf销毁到生成新的supertabs慢,导致滑动会寻找销毁的tabs,从而报错                setTimeout(() => {                    if (this.superTabs) {                        this.superTabs.slideTo(this._tabIndex);                    }                }, intervalTime)                this.global.remove('segment');                this.global.remove('tabIndex');            }, intervalTime);        }        this.firstEntry = false;        // 清空搜索筛选内容        window['search_input_content'] = '';        window['search_input_screen'] = '';        window['search_input_statu'] = 'all';        window['search_input_time'] = '';    }    ionViewDidEnter() {        // 子类才调用        let activePages = this.navCtrl.getActiveChildNavs();        if (!activePages || (activePages && !activePages.length)) {            window['epInstance']['emit']('refresh_task_node_count');        }    }    /**     * 获取子页面实例     */    getChildPageInstnce() {        let instance;        let childNav = this.navCtrl.getActiveChildNav();        if (!childNav || (childNav && !childNav.getActiveTab)) {            return;        }        let views = childNav.getActiveTab().getViews();        if (views && views[0]) {            instance = views[0]['instance'];        }        return instance;    }

all-task.ts (一个子页面做覆盖父类的该周期)

ionViewDidLoad() {}ionViewWillEnter() {  this.saveStatu = 'all'  this.queryStatu = '';  this.requestData(this.newTask, false, '');}

以上是最大的一个坑,下面是项目需求对组件的扩展

一、上边tab栏文字输入有长度要求,当超过长度会出现显示异常解决方案:

 

 

参考文章:

转载于:https://my.oschina.net/u/2949632/blog/1475364

你可能感兴趣的文章
《JavaScript和jQuery实战手册(原书第2版)》——第3章为程序添加逻辑和控制
查看>>
Google一年检测出超过76万个恶意网站
查看>>
遵义市 大数据产业汇聚八方人才
查看>>
教会委员会呼吁奥巴马宽恕斯诺登
查看>>
《Android的设计与实现:卷I》——第3章 3.6init循环监听处理事件
查看>>
联发科与高通平分秋色,消费者真不在乎处理器?
查看>>
台湾移动市场电信服务价格竞争预计将放缓
查看>>
《领域特定语言》一2.6 设计优良的DSL从何而来
查看>>
IDC圈探营:山西联通太原云数据中心
查看>>
呼叫中心还是客户中心?
查看>>
如何选择适当的低照度红外摄像机
查看>>
惠普企业总裁表示边缘计算将推动本地部署数据中心的需求
查看>>
数据说话|新华三近百个项目通过泰尔实验室测试
查看>>
CloudCC CRM探讨CRM如何提高客户的盈利性
查看>>
印度迎来可再生能源产业大发展
查看>>
光伏制造业“融资难、融资贵”问题亟待破解
查看>>
Java Mail最基本的发送邮件例子
查看>>
《HTML 5与CSS 3 权威指南(第3版·上册)》——2.3 新增的属性和废除的属性
查看>>
《Total Commander:万能文件管理器》——第3.5节.选择文件
查看>>
《日志管理与分析权威指南》一导读
查看>>