mobx与自定义弹框组件(Dialog)的结合
2019-01-22 本文已影响0人
m_麻
在开始写弹框之前,需要确定实现以下效果:
效果图
效果需求:
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....