2016-03-04 41 views
0

使用React-Native并尝试学习ES6语法。我昨天有类似的问题,并得到了解决方案。我加如何使用ES6与原生

.bind(本)

我的我的函数调用,问题就解决了。我用另一个函数调用再次遇到了同样的问题,我无法追查发生了什么。错误消息是相同的。

未定义不是(评价 'this.props.drawer.open')一个对象

的功能是:

onClickMenu() { 
    this.props.drawer.open(); 
    } 

并且它被称为与该:

onPress={this.onClickMenu.bind(this)} 

这是整个代码。如果你看到的东西不是这个问题,看起来不对,请让我知道! *注意我已将“var”替换为“let”。从我读过的内容来看,正确的ES6语法可以在任何地方使用它?

'use strict'; 

const React = require('react-native'); 
const { 
    Text, 
    View, 
    Component, 
    StyleSheet, 
    SwitchAndroid 
} = React; 

import { Button } from 'react-native-material-design'; 
import Store from 'react-native-simple-store'; 
import Underscore from 'underscore'; 
import RNGMap from 'react-native-gmaps'; 
import Polyline from 'react-native-gmaps/Polyline'; 
import Icon from 'react-native-vector-icons/Ionicons'; 
import SettingsService from './../settings/settings.service'; 
//import subdivisions from './subdivisions.json'; 
import commonStyles from './../common/styles'; 

let accessToken = null; 
let userId = null; 
let routeId = null; 
let subdivisionId = null; 

SettingsService.init('Android'); 

class Map extends Component { 
    constructor(props) { 
    super(props) 
    this.state = { 
     odometer: 0, 
     mapWidth: 300, 
     mapHeight: 300, 
     enabled: false, 
     isMoving: false, 
     currentLocation: undefined, 
     locationManager: undefined, 
     paceButtonIcon: 'Start Trip', 
     navigateButtonIcon: 'navigate', 
     paceButtonStyle: commonStyles.disabledButton, 
     // mapbox 
     center: { 
     lat: 40.7223, 
     lng: -73.9878 
     }, 
     zoom: 10, 
     markers: [] 
    } 
    } 

    componentDidMount() { 
    Store.get('token').then((token) => { 
     accessToken = token.access_token; 
     userId = token.userId; 
    }); 
    let me = this, 
     gmap = this.refs.gmap; 

    this.locationManager = this.props.locationManager; 

    // location event 
    this.locationManager.on("location", function(location) { 
     console.log('- location: ', JSON.stringify(location)); 
     me.setCenter(location); 
     gmap.addMarker(me._createMarker(location)); 

     me.setState({ 
     odometer: (location.odometer/1000).toFixed(1) 
     }); 

     // Add a point to our tracking polyline 
     if (me.polyline) { 
     me.polyline.addPoint(location.coords.latitude, location.coords.longitude); 
     } 
    }); 
    // http event 
    this.locationManager.on("http", function(response) {}); 
    // geofence event 
    this.locationManager.on("geofence", function(geofence) {}); 
    // error event 
    this.locationManager.on("error", function(error) { 
     console.log('- ERROR: ', JSON.stringify(error)); 
    }); 
    // motionchange event 
    this.locationManager.on("motionchange", function(event) { 
     me.updatePaceButtonStyle(); 
    }); 

    // getGeofences 
    this.locationManager.getGeofences(function(rs) { 
    }, function(error) { 
     console.log("- getGeofences ERROR", error); 
    }); 

    SettingsService.getValues(function(values) { 
     values.license = "eddbe81bbd86fa030ea466198e778ac78229454c31100295dae4bfc5c4d0f7e2"; 
     values.orderId = 1; 
     values.stopTimeout = 0; 
     //values.url = 'http://192.168.11.120:8080/locations'; 

     me.locationManager.configure(values, function(state) { 
     me.setState({ 
      enabled: state.enabled 
     }); 
     if (state.enabled) { 
      me.initializePolyline(); 
      me.updatePaceButtonStyle() 
     } 
     }); 
    }); 

    this.setState({ 
     enabled: false, 
     isMoving: false 
    }); 
    } 
    _createMarker(location) { 
    return { 
     title: location.timestamp, 
     id: location.uuid, 
     icon: require("image!transparent_circle"), 
     anchor: [0.5, 0.5], 
     coordinates: { 
     lat: location.coords.latitude, 
     lng: location.coords.longitude 
     } 
    }; 
    } 

    initializePolyline() { 
    // Create our tracking Polyline 
    let me = this; 
    Polyline.create({ 
     width: 12, 
     points: [], 
     geodesic: true, 
     color: '#2677FF' 
    }, function(polyline) { 
     me.polyline = polyline; 
    }); 
    } 

    onClickMenu() { 
    this.props.drawer.open(); 
    } 

    onClickEnable() { 
    let me = this; 
    if (!this.state.enabled) { 
     this.locationManager.start(function() { 
     me.initializePolyline(); 
     }); 
    } else { 
     this.locationManager.resetOdometer(); 
     this.locationManager.stop(); 
     this.setState({ 
     markers: [{}], 
     odometer: 0 
     }); 
     this.setState({ 
     markers: [] 
     }); 
     if (this.polyline) { 
     this.polyline.remove(function(result) { 
      me.polyline = undefined; 
     }); 
     } 
    } 

    this.setState({ 
     enabled: !this.state.enabled 
    }); 
    this.updatePaceButtonStyle(); 
    } 

    onClickPace() { 
    if (!this.state.enabled) { 
     return; 
    } 
    let isMoving = !this.state.isMoving; 
    this.locationManager.changePace(isMoving); 

    this.setState({ 
     isMoving: isMoving 
    }); 
    this.updatePaceButtonStyle(); 
    } 

    onClickLocate() { 
    let me = this; 

    this.locationManager.getCurrentPosition({ 
     timeout: 30 
    }, function(location) { 
     me.setCenter(location); 
    }, function(error) { 
     console.error('ERROR: getCurrentPosition', error); 
     me.setState({ 
     navigateButtonIcon: 'navigate' 
     }); 
    }); 
    } 

    onRegionChange() {} 

    setCenter(location) { 
    this.setState({ 
     navigateButtonIcon: 'navigate', 
     center: { 
     lat: location.coords.latitude, 
     lng: location.coords.longitude 
     }, 
     zoom: 16 
    }); 
    } 

    onLayout() { 
    let me = this, 
     gmap = this.refs.gmap; 

    this.refs.workspace.measure(function(ox, oy, width, height, px, py) { 
     me.setState({ 
     mapHeight: height, 
     mapWidth: width 
     }); 
    }); 
    } 

    updatePaceButtonStyle() { 
    let style = commonStyles.disabledButton; 
    if (this.state.enabled) { 
     style = (this.state.isMoving) ? commonStyles.redButton : commonStyles.greenButton; 
    } 
    this.setState({ 
     paceButtonStyle: style, 
     paceButtonIcon: (this.state.enabled && this.state.isMoving) ? 'Stop Trip' : 'Start Trip' 
    }); 
    } 

    render() { 
    return (
     <View style={commonStyles.container}> 
     <View style={commonStyles.topToolbar}> 
      <Icon.Button name="android-options" onPress={this.onClickMenu.bind(this)} backgroundColor="transparent" size={30} color="#000" style={styles.btnMenu} underlayColor={"transparent"} /> 
      <Text style={commonStyles.toolbarTitle}>Background Geolocation</Text> 
      <SwitchAndroid onValueChange={this.onClickEnable.bind(this)} value={this.state.enabled} /> 
     </View> 
     <View ref="workspace" style={styles.workspace} onLayout={this.onLayout.bind(this)}> 

      <RNGMap 
      ref={'gmap'} 
      style={{width: this.state.mapWidth, height: this.state.mapHeight}} 
      markers={this.state.markers} 
      zoomLevel={this.state.zoom} 
      onMapChange={(e) => console.log(e)} 
      onMapError={(e) => console.log('Map error --> ', e)} 
      center={this.state.center} /> 

     </View> 
     <View style={commonStyles.bottomToolbar}> 
      <Icon.Button name={this.state.navigateButtonIcon} onPress={this.onClickLocate.bind(this)} size={25} color="#000" underlayColor="#ccc" backgroundColor="transparent" style={styles.btnNavigate} /> 
      <Text style={{fontWeight: 'bold', fontSize: 18, flex: 1, textAlign: 'center'}}>{this.state.odometer} km</Text> 
      <Button raised={true} 
        text={this.state.paceButtonIcon} 
        onPress={this.onClickPace.bind(this)} 
        overrides={{backgroundColor:"#e12429",textColor:"#ffffff"}} 
        style={this.state.paceButtonStyle}></Button> 
      <Text>&nbsp;</Text> 
     </View> 
     </View> 
    ); 
    } 
}; 

const styles = StyleSheet.create({ 
    workspace: { 
    flex: 1 
    } 
}); 

module.exports = Map; 

UPDATE: 经由终端ADB调试示出了同样的错误 console

因此,这里是代码其余部分。排除故障。我将这些项目文件添加到了一个plunker。这是一个我正在使用的演示项目。 plunker

'use strict'; 

const React = require('react-native'); 
const { 
    Text, 
    Component, 
    StyleSheet, 
    AppRegistry 
} = React; 

import Map from './map/map'; 
import Drawer from 'react-native-drawer'; 
import Settings from './settings/settings.android'; 
import Icon from 'react-native-vector-icons/Ionicons'; 
import BackgroundGeolocation from 'react-native-background-geolocation-android'; 

global.bgGeo = BackgroundGeolocation; 

class App extends Component { 
    onClickMenu() { 
    this.props.refs.drawer.open(); 
    } 

    render() { 
    return (
     <Drawer ref="drawer" side="right" acceptPan={false} content={<Settings drawer={this.refs.drawer} locationManager={BackgroundGeolocation} />}> 
     <Map drawer={this.refs.drawer} locationManager={BackgroundGeolocation} />  
     </Drawer> 
    ); 
    } 
}; 

module.exports = App; 

UPDATE: screenshot

+0

我不认为你的代码显示哪些'道具'传递给你的组件,错误并没有指定哪一部分是未定义的。你假设context没有被传递,是否有可能'抽屉'(甚至'props')没有被定义?有些日志会证实它。 –

+0

好的,我如何获得日志? – texas697

+0

只需console.log,XCode将在运行应用程序时通过调试面板显示JS日志记录。 [更多信息](http://stackoverflow.com/questions/30115372/how-to-do-logging-in-react-native) –

回答

1

我不认为你可以通过参传递给部件以这样的方式, 肯定它不会在React工作,我不认为它会在这样一个工作 方式也在React-Native之内。

我不清楚为什么你从 Map组件试图.openDrawer,因为它看起来像Map部件仅能够 访问时,Drawer是开放的,但是,如果你想访问父 行为从孩子的一个好的模式是通过功能 为孩子执行(你可以争辩说,这实际上是不好的 和传递事件是一个更强大的模式)。

我从来没有使用的图书馆,所以我不上它的使用完全清楚,但 你可以通过传递函数是这样的:

class Application extends Component { 

    closeControlPanel =() => { 
    this.refs.drawer.close() 
    }; 
    openControlPanel =() => { 
    this.refs.drawer.open() 
    }; 
    render() { 
    return (
     <Drawer 
     ref="drawer" 
     content={<ControlPanel />} 
     > 
     <Map onMenuClose={ this.closeControlPanel.bind(this) } /> 
     </Drawer> 
    ) 
    } 
}) 

在这种情况下this.props.onMenuClose应附加到一个动作,这,执行时会触发父功能并执行this.refs.drawer.close功能。

+0

好的。我现在不在电脑上,但会尽快插上电源。这实际上是我的第一个反应原生项目,所以我正在学习。我把它作为一个演示项目,我想我会将它转换为ES6,以便与大多数项目保持一致。使用演示项目学习的问题是你永远不知道什么是笨蛋制作的 – texas697