mobx与自定义弹框组件(Dialog)的结合

在开始写弹框之前,需要确定实现以下效果:


效果图

效果需求:
1.点击请点击弹出弹框。
2.弹框的头部、中间内容、选项块的内容均为可变的。
3.弹框的大小随着框内内容的多少成比例扩大。
4.选项块的数量也可变,暂定最少1个,最多2个。
5.点击选项块后实现回调方法,也可不回调,也可能传的回调方法为空。
6.不能用modal,因为当两个modal同时出现时项目会崩,可用position实现。
技术点:
1.可利用mobox的观察者、也可用setState
2.弹框为封装好的组件,父组件中不可再使用state控制弹框的出现与否,而需要在弹框组件内部暴露出一个修改弹框内容state的函数,父组件用ref调用。
3.当子组件中使用了inject()方法调取数据时,注意this.refs.子组件ref值.子组件函数是会报错的,需要使用this.refs.子组件ref值.wrappedInstance.子组件方法
4.也可以为observable的数据与action封装一个store,只有调用它的store后才会刷新父组件。
实现过程:
1.封装Dialog组件

//Dialog.js
import React, { Component } from 'react';
import {
    StyleSheet,
    View,
    Text,
    Dimensions,
    TouchableOpacity,
} from 'react-native';
const { width, height } = Dimensions.get('window');
import { remove, getPixel } from '..';
import{observer,inject} from 'mobx-react';
import { observable } from 'mobx';
/*eslint-disable*/
//  @inject('rootStore')
@observer
export class Dialog extends Component{

    /**
     * from @marongting Tel 13269798391
     * content 弹窗是否出现控制器
     */
    @observable isFrameShow = false;

    constructor(props){
        super(props);
       
    }
    
    frameShow =() =>{
        this.isFrameShow = !this.isFrameShow;
    }
    render(){
        const {title,content,isCancel,isSubmit,cancel,submit} = this.props;
        return(
            <View style={{
                position:'absolute'}}>
                {
                    this.isFrameShow && 
                    <View style={{width:width,height:height,
                        backgroundColor:'rgba(0,0,0,0.5)',
                        position:'absolute',
                        alignItems:'center',
                        justifyContent:'center'}}>
                        <View style={{
                            borderRadius:getPixel(10),
                            backgroundColor:'#fff'}}>
                            <View style={{
                                alignItems:'center',
                                justifyContent:'center',
                                borderBottomWidth:StyleSheet.hairlineWidth,
                                borderBottomColor:'#cdcdcd',
                               
                            }}>
                                <Text allowFontScaling={false} style={{
                                fontSize:getPixel(18),
                                fontWeight:'bold',
                                lineHeight:getPixel(20),
                                marginHorizontal:getPixel(100),
                                marginTop:getPixel(20)
                            }}>
                            {
                             title ? title : '提示' 
                            }
                            
                            </Text>
                            <Text allowFontScaling={false} style={{
                                fontSize:getPixel(16),
                                lineHeight:getPixel(20),
                                marginVertical:getPixel(15),
                                marginHorizontal:getPixel(20),
                                maxWidth:getPixel(250),
                            }}>
                            {
                                content ? content :'确定要退出登录?'
                            }
                            
                            </Text>
                            </View>
                            <View style={{
                                flexDirection:'row',
                                }}>
                            {
                                isCancel &&
                                <TouchableOpacity style={{
                                    flex:1,
                                    alignItems:'center',
                                    justifyContent:'center',
                                }} 
                                onPress={
                                    ()=>{
                                        this.isFrameShow = false;
                                        this.props.cancelFunc && this.props.cancelFunc()
                                    }
                                }>
                                <Text style={{
                                    fontSize:getPixel(20),
                                    color:'green',
                                    lineHeight:getPixel(45)
                                }}>
                                {
                                    cancel ? cancel :'取消'
                                }
                                    
                                </Text>
                                </TouchableOpacity>
                            }
                            {
                                isCancel && isSubmit &&
                                <View style={{
                                    width:StyleSheet.hairlineWidth,
                                    height:getPixel(45),
                                    backgroundColor:'#cdcdcd'
                                }}></View>
                            }
                           {
                               isSubmit &&
                               <TouchableOpacity style={{
                                alignItems:'center',
                                justifyContent:'center',
                                flex:1,
                            }} onPress={
                                ()=>{
                                    this.isFrameShow = false;
                                    this.props.submitFunc && this.props.submitFunc();
                                }
                            }>
                            <Text style={{
                                fontSize:getPixel(20),
                                color:'green',
                                lineHeight:getPixel(45)
                            }}>
                            {
                                submit ? submit : '确定' 
                            }
                            </Text>
                            </TouchableOpacity>
                           }
                            
                            </View>
                        </View>
                  </View>
                }
            </View>
           
        )
    }
}

2.调用封装的Dialog组件

<TouchableOpacity 
                    style={{marginVertical:100}}
                    onPress={
                        ()=>{
                            /**
                             * from @marongting Tel 13269798391
                             * content 当子组件中的数据来源于inject时,调用子组件
                             * 的属性时需要使用如下方法:this.refs.子组件ref值
                             * .wrappedInstance.子组件方法
                             */
                            this.refs.Dialog.frameShow()
                        }
                    }>
                    <Text>请点击</Text>
                </TouchableOpacity>

 <Dialog 
                    ref='Dialog'
                    // title='标题'           //弹出框头部内容    
                    // content='不再玩会吗'    //弹出框内容
                    // cancel='狠心离开'        //弹出框左侧选项内容
                    // submit='继续'          //弹出框右侧选项内容
                    isCancel={true}           //弹出框左侧选项控制器
                    isSubmit={true}            //弹出框右侧选项控制器
                    cancelFunc = {            //弹出框左侧选项回调方法
                        ()=>{ 
                           
                        }
                    }
                    submitFunc = {              //弹出框右侧选项回调方法
                        ()=>{
                            console.log('console log for chrom 111',);
                        }
                    }
                    />

心得:

onPress={
this.props.cancelFunc
}

onPress={
()=>{
this.isFrameShow = false;
this.props.cancelFunc();
}
}

的区分,,真的是浪费了好久..以前写过,没整理,记混了。。
其实二者效果一样,只是一个只调用了父组件的方法,另外一个在调用父组件方法的同时也调用了自己的方法..
2.父组件调用子组件的值、方法:使用refs...
子组件调用父组件的值、方法:使用this.props....

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容