美文网首页
React Native(iOS)新手小白零基础自学(九)常用A

React Native(iOS)新手小白零基础自学(九)常用A

作者: 神魔狼 | 来源:发表于2016-06-01 13:50 被阅读1030次

    1.AppRegistry

    /*
          AppRegistry负责注册运行React Native应用程序的入口。通过AppRegistry.registerComponent来注册,当注册完成后,
          Native系统(Objective-C)就会加载jsbundle文件并且触发AppRegistry.runApplication运行应用。有以下方法:
          1.registerConfig(config: Array<AppConfig>):静态方法,注册配置。
          2.registerComponent(appKey: string, getComponentFunc: ComponentProvider):注册入口组件。
          3.registerRunnable(appKey: string, func: Function):注册函数监听。
          4.getAppKeys():获取registerRunnable注册的监听键。
          5.runApplication(appKey: string, appParameters: any):运行App。
     */
    
    启动应用时,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
    
    其实,上面的日志是由runApplication打印出来的,添加如下代码:
    alert(AppRegistry.runApplication);
    AppRegistry.registerComponent('InformationServicesRN', () => app);
    

    效果图如下:


    7074268D-FFDA-4E98-BCA8-29F8D11287EE.png

    runApplication函数中的console.log()打印的正是我们启动时的日志。
    也可以使用registerRunnable注册一些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是一个简单的、具有异步特性的键值对的存储系统。相对整个App而言,它是全局的,应该用于替代LocalStorage。
        AsyncStorage提供了比较安全的方法供我们使用。每个方法都有一个回调函数,而回调函数的第一个参数都是错误对象。如果发生错误该对象就会展示错误信息,否则为null。所有的方法执行后,都会返回一个Promise对象。具体的方法如下所示:
          1.static getItem(key: string, callback:(error, result)): 根据键来获取值,获取的结果会在回调函数中。
          2.static setItem(key: string, value: string, callback:(error)):设置键值对。
          3.static removeItem(key: string, callback:(error)):根据键移除一项。
          4.static mergeItem(key: string, value: string, callback:(error)):合并现有值和输入值。
          5.static clear(callback:(error)):清除所有的项目。
          6.static getAllKeys(callback:(error)):获取所有的键。
          7.static multiGet(keys, callback:(error, result)):获取多项,其中keys是字符串数组。
          8.static multiSet(keyValuePairs, callback:(error)):设置多项,其中keyValuePairs是字符串的二维数组。
          9.static multiRemove(keys, callback:(error)):删除多项,其中keys是字符串数组。
          10.static multiMerge(keyValuePairs, callback:(error)):多个键值对合并,其中keyValuePairs是字符串的二维数组。
     */
    

    以购物车为例,来看看效果:

    2.1 数据模型构建
    这里以购买水果为例定义一个静态的商品数组。

    var Model = [
      {
        id: '1',
        title: '佳沛新西兰进口猕猴桃',
        desc: '12个装',
        price: 99,
        url: 'http://vczero.github.io/ctrip/guo_1.jpg'
      },
      {
        id:'2',
        title: '墨西哥进口牛油果',
        desc: '6个装',
        price: 59,
        url: 'http://vczero.github.io/ctrip/guo_2.jpg'
      },
      {
        id:'3',
        title: '美国加州进口车厘子',
        desc: '1000g',
        price: 91.5,
        url: 'http://vczero.github.io/ctrip/guo_3.jpg'
      },
      {
        id:'4',
        title: '新疆特产西梅',
        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 列表项组件
    用于渲染商品的图片和名称

    //TouchableOpacity:透明触摸。用户点击时,点击的组件会出现透明效果。
    //resizeMode="contain" : 图片缩放模型,"contain"自适应所在容器模式
    //这里press点击事件、url、title都由父组件List传递过来
    
    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
        };
      },
      //在组件第一次绘制之后,会调用 componentDidMount() ,通知组件已经加载完成。
      componentDidMount: function(){
        var _that = this;
        AsyncStorage.getAllKeys(function(err, keys){
          if(err){
            //TODO:存储取数据出错
          }
          //将存储的商品条数反应到按钮上
          _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); //类似OC的数组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}>去结算{str}</Text>
          </ScrollView>
        );
      },
      goGouWu: function(){
        this.props.navigator.push({
          component: GouWu,
          title:'购物车'
        });
      },
      press:function(data){
        var count = this.state.count;
        count ++;
        //改变数字状态
        this.setState({
          count: count
        });
        //AsyncStorage存储
        AsyncStorage.setItem('SP-' + this.genId() + '-SP', JSON.stringify(data), function(err){
          if(err){
            //TODO:存储出错
          }
        });
      },
      //生成随机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 购物车组件
    购物车页面

    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}>清空购物车</Text>
          </ScrollView>
        );
      },
      componentDidMount: function(){
        var _that = this;
        AsyncStorage.getAllKeys(function(err, keys){
          if(err){
            //TODO:存储取数据出错
            //如果发生错误,这里直接返回(return)防止进入下面的逻辑
          }
          AsyncStorage.multiGet(keys, function(errs, result){
            //TODO:错误处理
            //得到的结果是二维数组
            //result[i][0]表示我们存储的键,result[i][1]表示我们存储的值
            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('购物车已经清空');
          }
          //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

    相关文章

      网友评论

          本文标题:React Native(iOS)新手小白零基础自学(九)常用A

          本文链接:https://www.haomeiwen.com/subject/oxlgrttx.html