每次地圖標記更改時,我都想計算和更新我地圖的區域。所以我想從地圖上的標記創建一個可觀察並訂閱它:RxJS訂閱永不執行
class Map extends Component {
componentDidMount() {
const { store } = this.context
this.unsubscribe = store.subscribe(() => { })
const markers$ = Observable.from(this.props.markers)
markers$.subscribe(x => console.log('observable', x))
}
起初我只是console.logging標誌物 - 但最終我將要運行getRegionForCoordinates
,然後this.props.updateRegion
每當標記改變。什麼都沒有記錄到控制檯。我究竟做錯了什麼? this.props.markers
最初是一個空數組。
Map.js
import { StyleSheet } from 'react-native'
import React, { Component } from 'react'
import MapView from 'react-native-maps'
import { connect } from 'react-redux'
import {
Button,
Container
} from 'native-base'
import { Observable } from 'rxjs'
import selectMarkers from './markers.selector'
import { updateRegion } from './map.action'
import Icon from 'react-native-vector-icons/FontAwesome'
import { toggleMenu } from '../search-page/searchPage.action'
import mapStyle from './style'
const mapStateToProps = (state) => ({
region: state.get('map').get('region'),
markers: selectMarkers(state)
})
const mapDispatchToProps = (dispatch) => ({
onRegionChange: (region) => {
dispatch(updateRegion(region))
},
onToggleMenuClick:() => {
dispatch(toggleMenu())
}
})
const getRegionForCoordinates = (points) => {
// points should be an array of { latitude: X, longitude: Y }
let minX, maxX, minY, maxY;
// init first point
((point) => {
minX = point.latitude
maxX = point.latitude
minY = point.longitude
maxY = point.longitude
})(points[0])
// calculate rect
points.map((point) => {
minX = Math.min(minX, point.latitude)
maxX = Math.max(maxX, point.latitude)
minY = Math.min(minY, point.longitude)
maxY = Math.max(maxY, point.longitude)
})
const midX = (minX + maxX)/2
const midY = (minY + maxY)/2
const deltaX = (maxX - minX)
const deltaY = (maxY - minY)
return {
latitude: midX,
longitude: midY,
latitudeDelta: deltaX,
longitudeDelta: deltaY
}
}
class Map extends Component {
componentDidMount() {
const { store } = this.context
this.unsubscribe = store.subscribe(() => { })
const markers$ = Observable.from(this.props.markers)
markers$.subscribe(x => console.log('observable', x))
}
componentWillUnmount() {
this.unsubscribe()
}
render() {
return (
<Container>
<MapView
style={styles.map}
region={this.props.region}
onRegionChangeComplete={this.props.onRegionChange}
>
{
this.props.markers.map(marker => {
return (
<MapView.Marker
coordinate={{ latitude: marker.latitude, longitude: marker.longitude }}
title={marker.name}
/>
)
})}
</MapView>
<Button
small
icon
style={mapStyle.toggleMenuButton}
onPress={() => this.props.onToggleMenuClick()}>
<Icon name="sliders" size={20} color="#FFFFFF" />
</Button>
</Container>
)
}
}
Map.contextTypes = {
store: React.PropTypes.object
}
Map.propTypes = {
region: React.PropTypes.shape({
latitude: React.PropTypes.number,
longitude: React.PropTypes.number,
latitudeDelta: React.PropTypes.number,
longitudeDelta: React.PropTypes.number
}).isRequired,
onRegionChange: React.PropTypes.func.isRequired,
onToggleMenuClick: React.PropTypes.func.isRequired,
markers: React.PropTypes.array
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Map)
const styles = StyleSheet.create({
map: {
...StyleSheet.absoluteFillObject,
zIndex: -1
}
})
markers.selector.js
import { createSelector } from 'reselect'
const searchResultsSelector = state => {
return state.get('searchResults')
}
const selectMarkers = createSelector(
searchResultsSelector,
(searchResults) => {
const shops = searchResults ? searchResults.map(result => {
return result.shops.map(shop => {
return {
id: shop.f1,
name: shop.f2,
latitude: shop.f4,
longitude: shop.f3
}
})
}) : searchResults
const shopIds = []
const flattenedShops = [].concat.apply([], shops)
const uniqueShops = flattenedShops.map(shop => {
if (!shopIds.includes(shop.id)) {
shopIds.push(shop.id)
return shop
}
})
const finalMarkers = uniqueShops.filter(n => n != undefined)
return finalMarkers
}
)
export default selectMarkers
當調用Observable.from時,observable是從'this.prop.markers'的**當前**值創建的。 'Observable.from'不會建立從數組到動態鏈接的可觀察性。當'this.props.markers'發生變化時,你需要做'send'到'Subject'。 – 2017-06-04 01:53:54
@torazaburo謝謝。我真的很努力去實現這個主題。當'props.markers'發生變化時我無法觸發'next()' – BeniaminoBaggins
JS中沒有「觀察」或「觀察」某些變量或數組的概念。你必須安排知道什麼時候'this.props.markers'改變,或者改變了,或者可能改變了。 – 2017-06-04 03:16:41