reactjs – React Google Map DirectionsRenderer Issue
发布时间:2020-12-15 20:32:02 所属栏目:百科 来源:网络整理
导读:因为我想在React中创建从当前位置到特定点击标记的Route.为了实现这个我使用React谷歌地图库( react-google-maps)和它的方向示例( Direction Example)但不幸的是我无法在React组件中调用新的google.maps.DirectionsService()方法.它给了我错误,因为google未
因为我想在React中创建从当前位置到特定点击标记的Route.为了实现这个我使用React谷歌地图库(
react-google-maps)和它的方向示例(
Direction Example)但不幸的是我无法在React组件中调用新的google.maps.DirectionsService()方法.它给了我错误,因为google未定义.对于相同的场景已经存在未解决的问题(
google is undefined)
解决方法
为了在窗口级访问google类,我创建了简单的javascript文件.
UserDetails.js module.exports = { "Steepless": { directionsService: new google.maps.DirectionsService(),directionsRenderer: new google.maps.DirectionsRenderer(),elevationService: new google.maps.ElevationService(),travelMode: google.maps.TravelMode.DRIVING,directionStatus: google.maps.DirectionsStatus.OK,longestDistance: 0,highestElevation: 0,lowestElevation: Infinity,chartWidth: 400,chartBarWidth: 2 },getOrigin: function (lat,lng) { var origin = new google.maps.LatLng(lat,lng); return origin; },getDestination: function (lat,lng) { var destination = new google.maps.LatLng(lat,lng); return destination; } }; reactComponent.jsx import * as React from "react"; var config = require("./Config"); var $= require('jquery'); var _this; var userDetails = require("./api/UserDetails"); var _ = require("lodash") var modelState = undefined; const { Button,Popover,Modal,Tooltip,OverlayTrigger,Accordion,Panel,Row,Col } = require("../../../../../../node_modules/react-bootstrap"); var GoogleMapLib = require("../../../../../../node_modules/react-google-maps"); var GoogleMap = GoogleMapLib.GoogleMap; var withGoogleMap = GoogleMapLib.withGoogleMap; var Marker = GoogleMapLib.Marker; var InfoWindow = GoogleMapLib.InfoWindow; var Direction = GoogleMapLib.DirectionsRenderer; var buyNow; import "../styles/glyphs-style.scss"; import ReferFriend from "./ReferFriend"; import SaleAlert from "./SaleAlert"; import WishListButton from "./WishListButton"; var ProductDetails = React.createClass({ getInitialState: function () { return { appended: '',showModal: true,isLoding: 'none',cordinates: '',morelikethis: '',merchantCollection: '',getParent: false,acoordianData: '',markers: [{ position: { lat: 40.712784,lng: -74.005941,},key: `New York`,defaultAnimation: 2 }],center: { lat: parseFloat('40.712784'),lng: parseFloat('-74.005941'),route: '',zoom: 7,showInfo: false,mywishlistLable: 'ADD TO LIST',saleAlertLable: 'GET SALE ALERT',wishListChecked: 'glyphicon-heart-empty',rawRelated: '' }; },contextTypes: { router: React.PropTypes.object.isRequired },/*Model related stuffs */ close() { userDetails.changeProductDetailsStatus(false); this.setState({ mywishlistLable: 'ADD TO LIST' }); this.setState({ wishListChecked: 'glyphicon-heart-empty' }); this.setState({ showModal: false }); modelState = true; },open() { this.setState({ showModal: true }); },/*Map related stuff*/ handleMapLoad: function (map) { this._mapComponent = map; if (map) { console.log(map.getZoom()); } },/* * This is called when you click on the map. * Go and try click now. */ handleMapClick: function (event) { const nextMarkers = [ ...this.state.markers,{ position: event.latLng,defaultAnimation: 2 },]; this.setState({ markers: nextMarkers,}); if (nextMarkers.length === 3) { this.props.toast( `Right click on the marker to remove it`,`Also check the code!` ); } },// Toggle to 'true' to show InfoWindow and re-renders component handleMarkerClick: function (targetMarker) { var showType; var markers = this.state.markers.map(function (item,i) { if (item.key === targetMarker.key) { showType = true; var geoDetails = userDetails.getUserGeoInfo(); var destination = userDetails.getDestination(targetMarker.position.lat,targetMarker.position.lng); var origin = userDetails.getOrigin(geoDetails.lat,geoDetails.lng); console.log(userDetails.Steepless.directionsService); userDetails.Steepless.directionsService.route({ origin: origin,destination: destination,travelMode: userDetails.Steepless.travelMode,(result,status) => { if (status === userDetails.Steepless.directionStatus) { this.setState({ route: result,}); } else { console.error(`error fetching directions ${result}`); } }); } else { showType = item.showInfo; } return { position: { lat: parseFloat(item.position.lat),lng: parseFloat(item.position.lng) },key: i,showInfo: showType,infoContent: ( item.infoContent) } }.bind(this)); this.setState({ markers: markers }) },handleMarkerClose: function (targetMarker) { var showType; var markers = this.state.markers.map(function (item,i) { if (item.key === targetMarker.key) { showType = false; } else { showType = item.showInfo; } return { position: { lat: parseFloat(item.position.lat),infoContent: ( item.infoContent) } }.bind(this)); this.setState({ markers: markers }) },handleMarkerRightClick: function (targetMarker) { /* * All you modify is data,and the view is driven by data. * This is so called data-driven-development. (And yes,it's now in * web front end and even with google maps API.) */ const nextMarkers = this.state.markers.filter(marker => marker !== targetMarker); this.setState({ markers: nextMarkers,}); },getInfoContents: function (item) { },GetModelInfo: function () { this.GetProdInfo(); var geoDetails = userDetails.getUserGeoInfo(); if (geoDetails) { this.setState({ center: { lat: parseFloat(geoDetails.lat),lng: parseFloat(geoDetails.lng) } }); var lat = geoDetails.lat; var lng = geoDetails.lng; } else { var lat = null; var lng = null; } this.setState({ cordinates: geoDetails }); $.ajax({ url: config.magentoBaseUrl + config.MORE_LIKE_THIS,dataType: 'json',cache: false,type: 'POST',data: { category_name: this.props.productInfo.category_name,brand: this.props.productInfo.brand,product_category_ids: this.props.productInfo.product_category_ids,_id: this.props.productInfo._id,lat: lat,lng: lng,merchant_id: this.props.productInfo.merchant_id,storename: this.props.productInfo.store_name },success: function (data) { if (data.productData) { //this.setState({morelikethis:data.productData}) this.setState({ rawRelated: data.productData }) var merchantData = JSON.parse(data.merchantData); if (merchantData) { this.setState({ acoordianData: merchantData }); var markers = merchantData.map(function (item,i) { return { position: { lat: parseFloat(item.latitude),lng: parseFloat(item.longitude) },key: item.storename,infoContent: ( this.getInfoContents(item)) } }.bind(this)); this.setState({ markers: markers }) } } }.bind(this),error: function (xhr,status,err) { }.bind(this) }); },GetProdInfo: function () { var details = userDetails.getUserInfo(); if (details) { var prodCheckData = { cust_id: details.id,skuNumber: this.props.productInfo.sku_number,userEmail: details.email } } $.ajax({ url: config.magentoBaseUrl + config.wishlist_action + 'prod_avail/',data: prodCheckData,success: function (data) { if (data.wishdata == "exist") { this.setState({ mywishlistLable: 'ADDED IN LIST' }); this.setState({ wishListChecked: 'glyphicon-heart' }); } }.bind(this),getHome: function () { this.setState({ getParent: true }); },wishListAction: function () { var details = userDetails.getUserInfo(); //userDetails.changeProductDetailsStatus(false); if (details) { if (this.state.wishListChecked === "glyphicon-heart-empty") { this.wishListTransactcion('add/',details); this.setState({ wishListChecked: 'glyphicon-heart' }); this.setState({ mywishlistLable: 'ADDED IN LIST' }); } if (this.state.wishListChecked === "glyphicon-heart") { this.wishListTransactcion('remove/',details); this.setState({ wishListChecked: 'glyphicon-heart-empty' }); this.setState({ mywishlistLable: 'ADD TO LIST' }); } } else { this.context.router.push('/'); userDetails.setOpenLoginModal('true'); } },wishListTransactcion: function (action,details) { var wishlistData = { cat_id: this.props.productInfo.product_category_ids[0],cust_id: details.id,userEmail: details.email,merchantName: this.props.productInfo.store_name,merchantId: this.props.productInfo.merchant_id,aprice: this.props.productInfo.actual_price,dprice: this.props.productInfo.discount_price },url = config.magentoBaseUrl + config.wishlist_action + action; $.ajax({ url: url,data: wishlistData,success: function (data) { userDetails.setWishlistCount(data); this.context.router.push('/'); this.setState({ tempState: 'true' }); }.bind(this),err) { }.bind(this) }); },getSavedPrice: function (aPrice,dPrice) { var percentDiff,convertedPrice,diff = (aPrice - dPrice) / aPrice * 100; percentDiff = diff.toFixed(0); convertedPrice = (aPrice - dPrice); convertedPrice = this.addCommas(convertedPrice.toFixed(2)); return "<span class='save-price'>You Save <span>$" + (convertedPrice + " " + "(" + percentDiff + "%)"); },addCommas: function (nStr) { nStr += ''; var x = nStr.split('.'); var x1 = x[0]; var x2 = x.length > 1 ? '.' + x[1] : ''; var rgx = /(d+)(d{3})/; while (rgx.test(x1)) { x1 = x1.replace(rgx,'$1' + ',' + '$2'); } return x1 + x2; },render() { var containerProps = { className: 'items-map' }; var route = this.state.route; const GettingStartedGoogleMap = withGoogleMap(props => ( <GoogleMap ref={props.onMapLoad} zoom={this.state.zoom} center={this.state.center} onClick={props.onMapClick} > <Marker icon={config.current_location_marker} key="100" position={this.state.center} > </Marker> {this.state.markers.map((marker,index) => ( <Marker icon={config.marker} key={index} position={marker.position} onClick={() => props.onMarkerClick(marker)} > {marker.showInfo && ( <InfoWindow onCloseClick={() => props.onMarkerClose(marker)}> <div dangerouslySetInnerHTML={{ __html: marker.infoContent }}></div> </InfoWindow> )} </Marker> ))} {route ? <Direction directions={route} options={{ polylineOptions: { strokeColor: 'green' },suppressMarkers: true}} /> : null } </GoogleMap> )); var actualPrice = ''; var discountPrice; var price_html = ''; if (this.props.productInfo.discount_price == null) { discountPrice = 0; } if (parseFloat(this.props.productInfo.discount_price) != 0 && parseFloat(this.props.productInfo.actual_price) != 0) { if (parseFloat(this.props.productInfo.discount_price) < parseFloat(this.props.productInfo.actual_price)) { actualPrice = parseFloat(this.props.productInfo.actual_price).toFixed(2) actualPrice = this.addCommas(actualPrice); discountPrice = parseFloat(this.props.productInfo.discount_price).toFixed(2) discountPrice = this.addCommas(discountPrice); } else { actualPrice = parseFloat(this.props.productInfo.actual_price).toFixed(2) discountPrice = this.addCommas(actualPrice); discountPrice = ''; } } else if (this.props.productInfo.discount_price != 0) { discountPrice = parseFloat(this.props.productInfo.discount_price).toFixed(2) discountPrice = this.addCommas(discountPrice); //discountPrice = ''; } else if (this.props.productInfo.actual_price != 0) { actualPrice = parseFloat(this.props.productInfo.actual_price).toFixed(2) actualPrice = this.addCommas(actualPrice); discountPrice = ''; } if (discountPrice != 0 && discountPrice != '') { var savedPrice = this.getSavedPrice(this.props.productInfo.actual_price,this.props.productInfo.discount_price); } return ( <Modal onEnter={this.GetModelInfo} show={this.props.dataFlag === this.state.showModal ? this.props.dataFlag : this.state.showModal} onHide={this.close} bsSize="large" aria-labelledby="contained-modal-title-lg"> <Modal.Header closeButton> <span onClick={this.close} data-dismiss="modal" aria-label="Close" className="visible-xs glyphicon arrow-left-css glyphicon-arrow-left"></span> </Modal.Header> <a onClick={this.close} className="hidden-xs prod-details-close"><img className="prod-details-close-img" src={require('../images/close_24.png')} /></a> <Modal.Body> <div> {!this.state.getParent ? <div> <div> {this.state.acoordianData ? <div id="map-canvas"> <GettingStartedGoogleMap containerElement={ <div style={{ height: `100%` }} /> } mapElement={ <div style={{ height: `100%` }} /> } center={this.state.center} markers={this.state.markers} onMarkerClick={this.handleMarkerClick} onMarkerClose={this.handleMarkerClose} /> </div> : null} <div className="container-fluid"> <div className="row"> <div className="hidden-xs col-sm-12 col-md-3 col-lg-3 product-store-locator-div"> <div className="stiky-store-locator-div filter"> <div className="store-locator-section-title"> <span>Store Locator</span> </div> <hr className="store-locator-title-hr" /> </div> </div> <div className="col-sm-12 col-md-9 col-lg-9 product-details-div"> <div className="product-details-top-section"> <div className="row breadcrum-div"> <div className="col-xs-12 col-sm-12 col-md-12 col-lg-12 breadcrumbs-title"> </div> </div> </div> <div className="row product-details-row-div"> <div className="col-xs-6 padding-0 col-sm-5 col-md-5 col-lg-4"> <div className="product-details-image-display-div center-block"> <div className="dummy-placeholder"></div> <div className="product-details-display-section-style center-block"> <img src={this.props.productInfo.product_image} className="img-responsive" alt="product image" /> </div> </div> </div> <div className="col-xs-6 col-sm-7 col-md-7 col-lg-5"> <div className="product-details-outer-div" > <div className="product-details-top-div"> <div className="product-brand-name-div"> <div className="product-details-brand-name">{this.props.productInfo.brand} </div> <div className="product-details-product-name">{this.props.productInfo.product_name}</div> </div> <div className="product-details-store-name">{this.props.productInfo.store_name}</div> {discountPrice ? <div className="old-price"> <del className="product-listing-details-old-price-div-less" dangerouslySetInnerHTML={{ __html: "$" + actualPrice }}> </del> <span className="product-listing-details-price-div" dangerouslySetInnerHTML={{ __html: "$" + discountPrice }}> </span> <div dangerouslySetInnerHTML={{ __html: savedPrice }}></div> </div> : <div className="old-price" dangerouslySetInnerHTML={{ __html: "$" + actualPrice }}></div> } <hr className="madal-hr-gray" /> <div className="product-details-description"> <div className="product-details-description-content"> <div className="product-details-description-title">Description</div> {this.props.productInfo.long_description} </div> </div> </div> <div className="product-details-bottom-div"> <div className="buy-from-retailer-btn-div"> <a target="_blank" href={this.props.productInfo.retailer_url} > <button type="button" className="btn buy-from-retailer-btn"> <span className="btn-detail-style">GO TO {this.props.productInfo.store_name}</span> </button> </a> </div> <div className="add-to-list-btn-div"> <span className="btn add-to-list-btn get-alert-detail-page" ><SaleAlert {...this.props.productInfo} /></span> </div> <div className="button-seprator"> </div> <div className="add-to-list-btn-div"> <button onClick={this.wishListAction} type="button" className="btn add-to-list-btn"> <span className={"add-to-list-btn-span glyphicon " + this.state.wishListChecked}></span>{this.state.mywishlistLable}</button> </div> </div> </div> </div> <div className="col-xs-12 col-sm-12 col-md-12 col-lg-3"> </div> </div> </div> </div> <div className="more-from-brand-div"> <h1 className="more-from-brand-link">More Like This</h1> </div> <hr className="madal-hr-gray" /> <div className="row product-listing-row-div" id="relatedProduct-data"> {this.getMoreLikeThisHtml(this.state.rawRelated,this)} </div> </div> </div> </div> : null } </div> </Modal.Body> </Modal> ); } }); export default ProductDetails; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
- 在Swift 1.2中声明不能同时是“final”和“dynam
- C语言压缩文件和用MD5算法校验文件完整性的实例教
- The maximum string content length quota (8192
- 如何在Ruby中将子类变量返回到父类中
- VB6可捕获错误的其他原因路径/文件访问错误(错误
- Vue 2.0 入门系列(10)Vue Ajax 的简单使用(wi
- ruby-on-rails – 如何将整数转换为二进制数组..
- 里氏代换原则(Liskov Substitution Principle LS
- Oracle11G impdp,empdp导入导出数据库操作流程
- PostgreSQL在存储函数中获取并释放LOCK
热点阅读