实例
在/app/host/components/houses/house_list.js文件中:
import React, {Component} from 'react';
import {StyleSheet, View, Text, Image, ListView, ScrollView, TouchableWithoutFeedback,TouchableOpacity} from 'react-native';
import {I18n, S, COLOR} from '../../utils/tools'
import RightAddBarButton from '../common/navigatorBar/rightAddBarButton'
import NavigationBar from 'react-native-navbar'
import HouseResource from './house_resources'
import Loading from '../loading'
import HouseManagePopup from '../helpPopup/house_manage_popup'
import RefreshInfiniteListView from '../refresh_infinite_list_view'
import HouseNothing from './house_nothing'
const ds = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
})
export default class HouseList extends Component {
static contextTypes = {
page: React.PropTypes.object
};
constructor(props) {
super(props)
}
componentDidMount() {
const {actions} = this.props
actions.fetchRoomsIfNeeded({page:1})
}
render() {
let titleConfig = {
title: I18n.t('house.house_manage'),
}
return(
<View style={[S.container, {backgroundColor: '#ededed'}]}>
<NavigationBar title={titleConfig}
rightButton = {<RightAddBarButton onPress = {() => this._onPress()}/>} />
{this._renderContent()}
</View>
)
}
_renderContent() {
var data = this.props.rooms.houses.items
var status = this.props.rooms.houses.status
let paging = this.props.rooms.houses.paging
if (status == 0) {
return (
<Loading/>
)
} else {
if (status == 200 && paging.total_pages == 0 || data.length == 0) {
return(
<View>
<HouseNothing />
<TouchableOpacity onPress={()=>this.onRefresh()}>
<View style={{alignItems:'center',height: 50,marginTop: 40}}>
<Text style={{fontSize: 14}}>{I18n.t(`common.retry`)}</Text>
</View>
</TouchableOpacity>
</View>
)
} else {
return (
<RefreshInfiniteListView
ref={(list) => {this.list = list}}
customize={true}
initialListSize={10}
dataSource={ds.cloneWithRows(data)}
renderHeader={() =>this._listHeader()}
renderRow={(rowData) => this._houseRenderRow(rowData)}
renderSeparator={this.renderSeparator}
scrollEventThrottle={10}
loadedAllData={() => this.loadedAllData()}
onInfinite={() => this.onInfinite()}
scrollEventThrottle={10}
onRefresh={() => this.onRefresh()}
>
</RefreshInfiniteListView>
)
}
}
}
onRefresh() {
const {actions} = this.props
actions.fetchRoomsIfNeeded({page:1})
}
loadedAllData() {
let paging = this.props.rooms.houses.paging
if (paging && paging.current_page && paging.total_pages) {
return paging.current_page >= paging.total_pages
}
}
onInfinite() {
const { actions } = this.props
var page = this.props.rooms.houses.paging.current_page
actions.fetchRoomsIfNeeded(
{
page: page + 1,
success: () => {
this.list.hideFooter()
}
}
)
}
_listHeader() {
return(
<TouchableWithoutFeedback onPress={()=>this._house_manage_popup()}>
<View style={styles.header}>
<Text style={{marginRight: 5}}>{I18n.t('house.house_manage')}</Text>
<Image source = {require('./img/help_ic.png')}/>
{this._manage_popup()}
</View>
</TouchableWithoutFeedback>
)
}
_manage_popup(){
return(
<HouseManagePopup ref={(c) => this.HouseManagePopup = c} />
)
}
_house_manage_popup(){
this.HouseManagePopup.openPopup();
}
_houseRenderRow(rowData) {
var house = this.props.rooms.data[`${rowData}`]
var dataArray = this.props.rooms.houses.data[`${rowData}`]
var rooms=[]
if (!_.isEmpty(dataArray)) {
_.map(dataArray,(element,index)=>{
var roomsMessages = this.props.rooms.data[`${element}`]
rooms.push(roomsMessages)
})
}
return(
<View>
<View style={[styles.cell,styles.border]}>
<HouseResource house={house} rooms={rooms} number={rowData}/>
</View>
</View>
)
}
renderSeparator() {
return (
<View></View>
)
}
_onPress() {
this.context.page.navigator.push({
id:'house_publish',
});
}
}
var padding = 10
const styles = StyleSheet.create({
cell:{
marginLeft: padding,
marginRight: padding,
marginBottom: padding,
backgroundColor: '#fafafa',
},
border: {
borderRadius: 2,
borderWidth:0.5,
borderColor:'#cdcdd3',
shadowRadius: 2,
shadowOpacity: 0.02,
shadowOffset: {
height: 1
}
},
header: {
marginLeft: padding,
marginRight: padding,
marginTop: 5,
marginBottom: 5,
justifyContent: 'flex-end',
flexDirection: 'row',
},
}); HouseList即是整个一个界面的组件
static contextTypes = {
page: React.PropTypes.object
};
这段函数是从最父组件/app/modal_container.js中以下这句继承而来:
childContextTypes: {
app: React.PropTypes.object,
page: React.PropTypes.object,
},
componentdidmount是render执行完后的回调函数
componentDidMount() {
const {actions} = this.props
actions.fetchRoomsIfNeeded({page:1})
}
整个过程是render执行{this._renderContent()}这个_render_Content()方法,render完全执行完之后执行ComponentDidMount这个回调函数, 然后再顺着ComponentDidMount()以后的东西, 也就是再执行一边render中的东西, 也就是渲染页面。
但回到ComponentDidMount()回调函数中的actions.fetchRoomsIfNeeded({page:1})
这个action在/app/host/actions/roomsActions.js中:
export function fetchRoomsIfNeeded(params = {}) {
return (dispatch, getState) => {
if (shouldFetchRooms(getState(),params)) {
return dispatch(fetchRooms(params, refresh = false))
}
}
} getState()为得到所有的整棵树, params即为上面函数中传进来的{page: 1}
先执行shouldFetchRooms(getState(),params)
function shouldFetchRooms(state, params) {
const houses = state.rooms
if (houses <= 0) {
return true
} else if (houses.isFetching) {
return false
} else {
return true
}
} 判断一些存在的值, 来验证, 然后执行
dispatch(fetchRooms(params, refresh = false))
先执行fetchRooms(params, refresh = false)
function fetchRooms(params) {
return (dispatch) => {
dispatch(requestRooms(params))
return Octopus.fetch({url: `/v1/houses.json`, body: {page:params.page}})
.then(response => response.json())
.then(responseData => {
if (responseData.meta.status == 403) {
dispatch({type: types.NEED_LOGIN, params: params})
} else {
dispatch(receiveRooms(params, responseData))
params.success && params.success(responseData.data)
}
})
.catch(reason => {
__LOG.info(` ${reason} ............................... `)
})
}
}
function requestRooms(params) {
__LOG.info(` start fetchMessages ---------------- `)
return {
type: types.REQUEST_ROOMS,
params: params
}
} 这个里面基本做一些数据的验证, 所以先不看
return Octopus.fetch({url: `/v1/houses.json`, body: {page:params.page}})这句是请求url并带着参数, 成功的话执行dispatch(receiveRooms(params, responseData))
receiveRooms(params, responseData)这个函数是function receiveRooms(params, responseData) { return { type: types.RECEIVE_ROOMS, rooms: responseData.data.houses, paging: responseData.meta.paging, status: responseData.meta.status, params: params, receivedAt: Date.now() } }在/app/host/actions/actionTypes.js这个文件中找action和reducer的对应关系(当然如果写的时候这里也要注册)跳到相应type的reducer中/app/host/reducers/rooms.jscase types.RECEIVE_ROOMS: var{data,houses}=state var dataArray = data var housesData=houses.data var itemsArray=houses.items action.rooms.forEach((item, index) => { var housesArray=[] _.uniq(itemsArray.push(item.number)) if (!_.isEmpty(item.roomings)) { var roomArray=[] item.roomings.forEach((element,index)=>{ dataArray[`${element.number}`]=element _.uniq(housesArray.push(element.number)) }) housesData[`${item.number}`]=housesArray dataArray[`${item.number}`]=_.omit(item,'roomings') }else { dataArray[`${item.number}`]=item housesData[`${item.number}`]=[] } }) houses = Object.assign({},houses, { isFetching: false, items:_.uniq(itemsArray), data: housesData, paging: action.paging, query: {}, status: action.status, }) return Object.assign({}, state, {data: dataArray,houses:houses}) break;对数据进行处理和合并到State大树中,action.paging即为action中最后执行dispath函数return所稍带的参数
3978

被折叠的 条评论
为什么被折叠?



