在 ViewModel 中链接可观察对象以获取但作为独立属性保留

Chain observables in ViewModel for fetch but leave as independent properties

我的MapViewController有一个MapViewModel

我有一个 MapObjectService 函数 fetchMapObjects(currentLocation: CLLocation) returns 一个 Observable<MapObjects>

在我的 MapViewModel 中:

var currentLocation: Observable<CLLocation?>
var mapObjects: Observable<MapObjects>

我可以这样初始化当前位置:

currentLocation = locationManager.rx.didUpdateLocations.map( { locations in
        return locations.filter() { loc in
            return loc.horizontalAccuracy < 20
            }.first
    })

如何有效地初始化这两个属性,以便 fetchMapObjects() 使用 currentLocation 来设置 mapObjects 属性?

我的计划是将这些属性绑定到 MapViewController 中的 mapView,以将地图对象显示为图钉和当前位置。

谢谢!

你可以这样做:

currentLocation = locationManager.rx.didUpdateLocations.map( { locations in
   return locations.filter() { loc in
      return loc.horizontalAccuracy < 20
   }.first
})

mapObjects = currentLocation.flatMap { loc in
   return MapObjectService.fetchMapObjects(currentLocation: loc)
}

您可以将 mapObjects 定义为 currentLocation 流的 延续

像这样:

currentLocation = locationManager.rx.didUpdateLocations.map { locations in
    return locations.first(where: { location -> Bool in
        return location.horizontalAccuracy < 20
    })
}

mapObjects = currentLocation.flatMapLatest { location -> Observable<MapObjects> in
    guard let location = location else {
        return Observable<String>.empty()
    }
    return fetchMapObjects(currentLocation: location)
}

这样,每次 currentLocation observable 发出一个位置,它将用于 fetchMapObjects 调用。

我在这里使用 flatMapLatest 而不是 flatMap,以便在调用完成之前发出新位置时放弃对 fetchMapObjects 的任何先前调用。

您还可以在 flatMapLatest 之前为 currentLocation 定义过滤,以防您想忽略其中的一些,例如当与前一个的距离太短时。

现在您只需订阅您的 mapObjects 可观察对象并处理任何发出的 MapObjects

mapObjects.subscribe(onNext: { objects in
    // handle mapObjects here
})