问题描述
我总是使用RxSwift将disposeBag放在MVVM的ViewController中,就像本主题中所说的那样:
On iOS,for the DisposeBag in MVVM,can it be placed in ViewModel?
但是使用Combine时,由于View是一个结构,并且不能在其中放置可取消的对象,因此我只能解决问题。
如何在合并中管理View和VM之间的订阅而又不可以在viewmodel中取消添加
或者也许,在SwiftUI / Combine中,没有选择将取消对象放置在VM中。
在SiwftUI / Combine中有一个实现示例:
class Equityviewmodel: ObservableObject {
@Injected private var api: AlphaVantageAPI
private var cancellables = Set<AnyCancellable>()
private let code: String
@Published private var result: Quote?
@Published var price: String = ""
init(code: String) {
self.code = code
self.$result
.map {
return "\($0?.price ?? 0) €"
}.assign(to: &$price)
}
func addToPortfolio(){
}
func onAppear() {
self.api.quote(symbol: self.code).share()
.sink { completion in }
receiveValue: { quote in
self.result = quote.quote
}
.store(in: &cancellables)
}
}
视图
struct EquityView: View {
@Observedobject var viewmodel: Equityviewmodel
init(viewmodel: Equityviewmodel) {
self.viewmodel = viewmodel
}
var body: some View {
ZStack {
Color("primary").edgesIgnoringSafeArea(.all)
vstack {
Text("Stock Price")
.foregroundColor(.white)
.frame(minWidth: 0,maxWidth: .infinity,alignment: .topLeading)
.padding()
HStack {
Text(self.viewmodel.price)
.foregroundColor(.white)
Text("+4.75 %")
.foregroundColor(.white)
.padding(.leading,20)
}.frame(minWidth: 0,alignment: .topLeading)
.padding()
Button(action: self.viewmodel.addToPortfolio,label: {
Text("Add to portfolio")
.foregroundColor(.white)
.frame(minWidth: 0,maxHeight: 30,alignment: .center)
.background(Color.blue)
.cornerRadius(5)
}).padding()
Spacer()
}
}.frame(alignment: .leading)
.onAppear(perform: self.viewmodel.onAppear)
}
}
解决方法
这就是您搜索的内容吗?我无法测试,我不知道您使用的是什么库
class EquityViewMode: ObservableObject {
// @Injected private var api: AlphaVantageAPI
var pricePublisher: AnyPublisher<String,Never>
@Published var price: String = ""
init(){
// init your publisher like
// pricePublisher = self.api.quote(symbol: self.code)
// .share()
// .map { "\($0?.price ?? 0) €" }
// .eraseToAnyPublisher()
}
struct EquityView: View {
@ObservedObject var viewModel: EquityViewModel
var handle: AnyCancellable? = nil
init(m:EquityViewMode) {
viewModel = m
handle = m.pricePublisher.assign(to: \.price,on: self.viewModel)
}
var body: some View{
Text(viewModel.price)
}
}