Mvvm 使用SwiftUI/Combine,如何避免在ViewModel中放置可取消项

Mvvm 使用SwiftUI/Combine,如何避免在ViewModel中放置可取消项,mvvm,swiftui,reactive-programming,rx-swift,combine,Mvvm,Swiftui,Reactive Programming,Rx Swift,Combine,我总是将DisposeBag in ViewController放在带有RxSwift的MVVM中,就像本主题中所说的: 但是使用combine,由于视图是一个结构,并且不能将cancelable放在其中,所以我只能使用这个解决方案 如何在联合收割机中管理视图和VM之间的订阅,而不在ViewModel中添加可取消项 class EquityViewModel: ObservableObject { @Injected private var api: AlphaVantag

我总是将DisposeBag in ViewController放在带有RxSwift的MVVM中,就像本主题中所说的:

但是使用combine,由于视图是一个结构,并且不能将cancelable放在其中,所以我只能使用这个解决方案

如何在联合收割机中管理视图和VM之间的订阅,而不在ViewModel中添加可取消项


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)
    }
    
}
或者,在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)
    }
    
}

这就是你要找的吗?我不能测试我不知道你在用什么图书馆

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)
    }
}
类EquityViewMode:ObserveObject{
//@var-api:AlphaVantageAPI
var pricePublisher:AnyPublisher
@已发布的var价格:String=“”
init(){
//你喜欢什么
//pricePublisher=self.api.quote(符号:self.code)
//.share()
//.map{“\($0?.price??0)€”}
//.删除任何发布者()
}
结构设备视图:视图{
@观察对象变量视图模型:EquityViewModel
变量句柄:anycancelable?=nil
初始化(m:EquityViewMode){
viewModel=m
handle=m.pricePublisher.assign(收件人:\.price,在:self.viewModel上)
}
var body:一些观点{
文本(viewModel.price)
}
}

你必须将它们存储在某个地方,那么让它靠近创建者又有什么不好呢?当然你必须避免引用循环,但你必须始终避免引用循环。顺便说一句,使用
接收器
而不是
分配
,不要忘记
[弱自我]
在相应的闭包中。订阅者应该拥有订阅。在您的示例中,
EquityViewModel
属性会随着发布值的变化而变化,因此它应该拥有它。或者,您可以提供发布者自己,并使用
onreceive(\uu:perform:)
订阅和更改一些状态变量