1.AppRegistry
/*
AppRegistry負(fù)責(zé)注冊(cè)運(yùn)行React Native應(yīng)用程序的入口。通過(guò)AppRegistry.registerComponent來(lái)注冊(cè)宁昭,當(dāng)注冊(cè)完成后摧扇,
Native系統(tǒng)(Objective-C)就會(huì)加載jsbundle文件并且觸發(fā)AppRegistry.runApplication運(yùn)行應(yīng)用局骤。有以下方法:
1.registerConfig(config: Array<AppConfig>):靜態(tài)方法,注冊(cè)配置。
2.registerComponent(appKey: string, getComponentFunc: ComponentProvider):注冊(cè)入口組件机久。
3.registerRunnable(appKey: string, func: Function):注冊(cè)函數(shù)監(jiān)聽(tīng)。
4.getAppKeys():獲取registerRunnable注冊(cè)的監(jiān)聽(tīng)鍵赔嚎。
5.runApplication(appKey: string, appParameters: any):運(yùn)行App膘盖。
*/
啟動(dòng)應(yīng)用時(shí),x-code日志輸出如下:
2016-05-19 13:48:28.777 [info][tid:com.facebook.react.JavaScript] Running application
"InformationServicesRN" with appParams: {"rootTag":1,"initialProps":{}}.
__DEV__ === true, development-level warning are ON,
performance optimizations are OFF
其實(shí)尤误,上面的日志是由runApplication打印出來(lái)的侠畔,添加如下代碼:
alert(AppRegistry.runApplication);
AppRegistry.registerComponent('InformationServicesRN', () => app);
效果圖如下:
7074268D-FFDA-4E98-BCA8-29F8D11287EE.png
runApplication函數(shù)中的console.log()打印的正是我們啟動(dòng)時(shí)的日志。
也可以使用registerRunnable注冊(cè)一些AppKey:
AppRegistry.registerRunnable('vczero', function(){
console.log('vczero');
});
AppRegistry.registerRunnable('react-native', function(){
console.log('react-native');
});
alert(AppRegistry.getAppKeys());
效果如下:
83B2201B-825E-41A8-8C92-D3F915237659.png
2.AsyncStorage
/*
AsyncStorage是一個(gè)簡(jiǎn)單的损晤、具有異步特性的鍵值對(duì)的存儲(chǔ)系統(tǒng)软棺。相對(duì)整個(gè)App而言,它是全局的尤勋,應(yīng)該用于替代LocalStorage喘落。
AsyncStorage提供了比較安全的方法供我們使用。每個(gè)方法都有一個(gè)回調(diào)函數(shù)最冰,而回調(diào)函數(shù)的第一個(gè)參數(shù)都是錯(cuò)誤對(duì)象揖盘。如果發(fā)生錯(cuò)誤該對(duì)象就會(huì)展示錯(cuò)誤信息,否則為null锌奴。所有的方法執(zhí)行后兽狭,都會(huì)返回一個(gè)Promise對(duì)象。具體的方法如下所示:
1.static getItem(key: string, callback:(error, result)): 根據(jù)鍵來(lái)獲取值鹿蜀,獲取的結(jié)果會(huì)在回調(diào)函數(shù)中箕慧。
2.static setItem(key: string, value: string, callback:(error)):設(shè)置鍵值對(duì)。
3.static removeItem(key: string, callback:(error)):根據(jù)鍵移除一項(xiàng)茴恰。
4.static mergeItem(key: string, value: string, callback:(error)):合并現(xiàn)有值和輸入值颠焦。
5.static clear(callback:(error)):清除所有的項(xiàng)目。
6.static getAllKeys(callback:(error)):獲取所有的鍵往枣。
7.static multiGet(keys, callback:(error, result)):獲取多項(xiàng)伐庭,其中keys是字符串?dāng)?shù)組粉渠。
8.static multiSet(keyValuePairs, callback:(error)):設(shè)置多項(xiàng),其中keyValuePairs是字符串的二維數(shù)組圾另。
9.static multiRemove(keys, callback:(error)):刪除多項(xiàng)霸株,其中keys是字符串?dāng)?shù)組。
10.static multiMerge(keyValuePairs, callback:(error)):多個(gè)鍵值對(duì)合并集乔,其中keyValuePairs是字符串的二維數(shù)組去件。
*/
以購(gòu)物車(chē)為例,來(lái)看看效果:
2.1 數(shù)據(jù)模型構(gòu)建
這里以購(gòu)買(mǎi)水果為例定義一個(gè)靜態(tài)的商品數(shù)組扰路。
var Model = [
{
id: '1',
title: '佳沛新西蘭進(jìn)口獼猴桃',
desc: '12個(gè)裝',
price: 99,
url: 'http://vczero.github.io/ctrip/guo_1.jpg'
},
{
id:'2',
title: '墨西哥進(jìn)口牛油果',
desc: '6個(gè)裝',
price: 59,
url: 'http://vczero.github.io/ctrip/guo_2.jpg'
},
{
id:'3',
title: '美國(guó)加州進(jìn)口車(chē)?yán)遄?,
desc: '1000g',
price: 91.5,
url: 'http://vczero.github.io/ctrip/guo_3.jpg'
},
{
id:'4',
title: '新疆特產(chǎn)西梅',
desc: '1000g',
price: 69,
url: 'http://vczero.github.io/ctrip/guo_4.jpg'
},
{
id:'5',
title: '陜西大荔冬棗',
desc: '2000g',
price: 59.9,
url: 'http://vczero.github.io/ctrip/guo_5.jpg'
},
{
id:'6',
title: '南非紅心西柚',
desc: '2500g',
price: 29.9,
url: 'http://vczero.github.io/ctrip/guo_6.jpg'
}
];
2.2 列表項(xiàng)組件
用于渲染商品的圖片和名稱(chēng)
//TouchableOpacity:透明觸摸尤溜。用戶點(diǎn)擊時(shí),點(diǎn)擊的組件會(huì)出現(xiàn)透明效果汗唱。
//resizeMode="contain" : 圖片縮放模型宫莱,"contain"自適應(yīng)所在容器模式
//這里press點(diǎn)擊事件、url哩罪、title都由父組件List傳遞過(guò)來(lái)
var Item = React.createClass({
render: function(){
return(
<View style={styles.item}>
<TouchableOpacity onPress={this.props.press}>
<Image
resizeMode="contain"
style={styles.img}
source={{uri:this.props.url}}>
<Text numberOfLines={1} style={styles.item_text}>{this.props.title}</Text>
</Image>
</TouchableOpacity>
</View>
);
}
});
2.3 列表組件
var List = React.createClass({
getInitialState: function(){
return{
count:0
};
},
//在組件第一次繪制之后授霸,會(huì)調(diào)用 componentDidMount() ,通知組件已經(jīng)加載完成识椰。
componentDidMount: function(){
var _that = this;
AsyncStorage.getAllKeys(function(err, keys){
if(err){
//TODO:存儲(chǔ)取數(shù)據(jù)出錯(cuò)
}
//將存儲(chǔ)的商品條數(shù)反應(yīng)到按鈕上
_that.setState({
count: keys.length
});
});
},
render: function() {
var list = [];
for(var i in Model){
if(i % 2 === 0){
var row = (
<View style={styles.row}>
<Item url={Model[i].url}
title={Model[i].title}
press={this.press.bind(this, Model[i])}></Item>
<Item
url={Model[parseInt(i)+1].url}
title={Model[parseInt(i)+1].title}
press={this.press.bind(this, Model[parseInt(i)+1])}></Item>
</View>);
list.push(row); //類(lèi)似OC的數(shù)組addObject
}
}
var count = this.state.count;
var str = null;
if(count){
str = '绝葡,共'+ count + '件商品';
}
return (
<ScrollView style={{marginTop:10}}>
{list}
<Text onPress={this.goGouWu} style={styles.btn}>去結(jié)算{str}</Text>
</ScrollView>
);
},
goGouWu: function(){
this.props.navigator.push({
component: GouWu,
title:'購(gòu)物車(chē)'
});
},
press:function(data){
var count = this.state.count;
count ++;
//改變數(shù)字狀態(tài)
this.setState({
count: count
});
//AsyncStorage存儲(chǔ)
AsyncStorage.setItem('SP-' + this.genId() + '-SP', JSON.stringify(data), function(err){
if(err){
//TODO:存儲(chǔ)出錯(cuò)
}
});
},
//生成隨機(jī)ID:GUID
genId:function(){
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
}).toUpperCase();
}
});
2.4 購(gòu)物車(chē)組件
購(gòu)物車(chē)頁(yè)面
var GouWu = React.createClass({
getInitialState: function(){
return {
data: [],
price: 0
};
},
render: function(){
var data = this.state.data;
var price = this.state.price;
var list = [];
for(var i in data){
price += parseFloat(data[i].price);
list.push(
<View style={[styles.row, styles.list_item]}>
<Text style={styles.list_item_desc}>
{data[i].title}
{data[i].desc}
</Text>
<Text style={styles.list_item_price}>¥{data[i].price}</Text>
</View>
);
}
var str = null;
if(price){
str = '深碱,共' + price.toFixed(1) + '元';
}
return(
<ScrollView style={{marginTop:10}}>
{list}
<Text style={styles.btn}>支付{str}</Text>
<Text style={styles.clear} onPress={this.clearStorage}>清空購(gòu)物車(chē)</Text>
</ScrollView>
);
},
componentDidMount: function(){
var _that = this;
AsyncStorage.getAllKeys(function(err, keys){
if(err){
//TODO:存儲(chǔ)取數(shù)據(jù)出錯(cuò)
//如果發(fā)生錯(cuò)誤腹鹉,這里直接返回(return)防止進(jìn)入下面的邏輯
}
AsyncStorage.multiGet(keys, function(errs, result){
//TODO:錯(cuò)誤處理
//得到的結(jié)果是二維數(shù)組
//result[i][0]表示我們存儲(chǔ)的鍵,result[i][1]表示我們存儲(chǔ)的值
var arr = [];
for(var i in result){
arr.push(JSON.parse(result[i][1]));
}
_that.setState({
data: arr
});
});
});
},
clearStorage: function(){
var _that = this;
AsyncStorage.clear(function(err){
if(!err){
_that.setState({
data:[],
price: 0
});
alert('購(gòu)物車(chē)已經(jīng)清空');
}
//TODO:ERR
});
}
});
2.5 完整的功能
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
Image,
NavigatorIOS,
ScrollView,
AsyncStorage,
TouchableOpacity,
} = React;
var Model = [...];
var Item = React.createClass({...});
var List = React.createClass({...});
var GouWu = React.createClass({...});
var App = React.createClass({
render: function() {
return (
<NavigatorIOS
style={styles.container}
initialRoute={
{
component: List,
title: '水果列表'
}
}/>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
},
row:{
flexDirection: 'row',
marginBottom: 10,
},
item:{
flex:1,
marginLeft:5,
borderWidth:1,
borderColor:'#ddd',
marginRight:5,
height:100,
},
img:{
flex:1,
backgroundColor: 'transparent'
},
item_text:{
backgroundColor: '#000',
opacity: 0.7,
color:'#fff',
height:25,
lineHeight:18,
textAlign:'center',
marginTop:74
},
btn:{
backgroundColor:'#FF7200',
height:33,
textAlign:'center',
color:'#fff',
marginLeft:10,
marginRight:10,
lineHeight:24,
marginTop:40,
fontSize:18,
},
list_item:{
marginLeft:5,
marginRight:5,
padding:5,
borderWidth:1,
height:30,
borderRadius:3,
borderColor:'#ddd'
},
list_item_desc:{
flex:2,
fontSize:15
},
list_item_price:{
flex:1,
textAlign:'right',
fontSize:15
},
clear:{
marginTop:10,
backgroundColor:'#FFF',
color:'#000',
borderWidth:1,
borderColor:'#ddd',
marginLeft:10,
marginRight:10,
lineHeight:24,
height:33,
fontSize:18,
textAlign:'center',
}
});
AppRegistry.registerComponent('App', () => App);
效果如下:
40678F6D-64FD-4F56-B96A-F7827CB78053.png
89816ECE-0325-4976-94AD-41CBBC7E6878.png