weex-nuke
Version:
基于 Rax 、Weex 的高性能组件体系 ~~
241 lines (231 loc) • 5.5 kB
Markdown
# github trends list
- order: 1
从 github 拉取热门趋势,演示网络请求与 ListView 综合使用。
---
```js
/** @jsx createElement */
import { View, Text, RefreshControl, Touchable, ListView, Iconfont, Navigator } from 'weex-nuke';
import { createElement, PureComponent, Component, render } from 'rax';
class ListItem extends PureComponent {
render() {
const { id, repo, url, stars, forks, description } = this.props;
return (
<Touchable
key={id}
style={styles.cellItem}
onPress={() => {
Navigator.push(url);
}}>
<Text style={styles.repo}>{repo}</Text>
<Text style={styles.desc}>{description}</Text>
<View style={styles.subLine}>
<Text style={styles.icon}></Text>
<Text style={styles.subtext}>{stars}</Text>
<Text style={styles.icon}></Text>
<Text style={styles.subtext}>{forks}</Text>
</View>
</Touchable>
);
}
}
class Loading extends PureComponent {
render() {
return (
<View style={styles.fullLoading}>
<Text style={styles.fullLoadingText}>loading...</Text>
</View>
);
}
}
class ListViewDemo extends Component {
constructor() {
super();
this.state = {
data: [],
isRefreshing: false,
refreshText: '↓ 下拉刷新'
};
this.onRefresh = this.onRefresh.bind(this);
this.renderItem = this.renderItem.bind(this);
this.onLoadMore = this.onLoadMore.bind(this);
this.renderHeader = this.renderHeader.bind(this);
this.renderFooter = this.renderFooter.bind(this);
this.page = 1;
}
componentDidMount() {
Iconfont({
name: 'trends',
url: 'https://at.alicdn.com/t/font_651722_e6h6njwk7f1or.ttf'
});
this.fetchData().then((data) => {
this.page = this.page + 1;
this.setState({
data: this.formatData(data.items)
});
});
}
fetchData() {
const that = this;
return fetch(
'https://api.github.com/search/repositories?q=created:%3C2018-04-30+language:javascript&sort=stars&order=desc&page=' +
this.page +
'&per_page=10',
{
mode: 'cors',
dataType: 'json',
method: 'GET'
}
).then((response) => {
return response.json();
});
}
formatData(data) {
data.map((item, index) => {
item = {
repo: item.full_name,
url: item.html_url,
stars: item.stargazers_count,
forks: item.forks_count,
description: item.description,
id: item.id
};
data[index] = item;
});
return data;
}
onItemPress(index) {
console.log(`clicked ${index}`);
}
onRefresh(e) {
this.page = 1;
this.setState({
isRefreshing: true,
refreshText: '加载中'
});
this.fetchData().then(
(data) => {
this.page = this.page + 1;
this.setState({
isRefreshing: false,
data: this.formatData(data.items),
refreshText: '↓ 下拉刷新'
});
},
(error) => {}
);
}
onLoadMore() {
this.fetchData().then((data) => {
this.page = this.page + 1;
let newdata = this.formatData(data.items);
this.setState({
data: this.state.data.concat(newdata)
});
this.refs.trendslist.resetLoadmore();
});
}
renderHeader() {
return (
<RefreshControl style={styles.refresh} refreshing={this.state.isRefreshing} onRefresh={this.onRefresh}>
<Text style={styles.loadingText}>{this.state.refreshText}</Text>
</RefreshControl>
);
}
renderItem(item, index) {
return <ListItem {...item} />;
}
renderFooter() {
return (
<View style={[styles.loading]}>
<Text style={styles.loadingText}>加载中...</Text>
</View>
);
}
render() {
const { data } = this.state;
// alert('length:' + data.length);
return data.length ? (
<ListView
ref="trendslist"
renderHeader={this.renderHeader}
renderFooter={this.renderFooter}
renderRow={this.renderItem}
dataSource={data}
style={styles.listContainer}
onEndReached={this.onLoadMore}
/>
) : (
<Loading />
);
}
}
const styles = {
listContainer: {
flex: 1
},
cellItem: {
backgroundColor: '#ffffff',
'backgroundColor:active': '#f2f3f7',
minHeight: 160,
width: 750,
padding: 30,
borderBottomWidth: 1,
borderBottomStyle: 'solid',
borderBottomColor: '#e6e7eb'
},
repo: {
fontSize: 40,
color: '#0366d6',
marginBottom: 30
},
desc: {
fontSize: 28,
color: '#999999',
marginBottom: 20
},
icon: {
fontSize: 32,
marginRight: 10,
lineHeight: 50,
color: '#5F646E',
fontFamily: 'trends'
},
subLine: {
flexDirection: 'row'
},
subtext: {
color: '#5F646E',
fontSize: 28,
lineHeight: 50,
marginRight: 40
},
refresh: {
height: 80,
width: 750,
backgroundColor: '#cccccc',
justifyContent: 'center',
alignItems: 'center'
},
loading: {
height: 80,
width: 750,
flexDirection: 'row',
backgroundColor: '#cccccc',
alignItems: 'center',
justifyContent: 'center'
},
loadingText: {
color: '#666666'
},
fullLoading: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
fullLoadingText: {
fontSize: 28,
color: '#999999'
}
};
render(<ListViewDemo />);
```