RxMVVM使用输入/输出和复杂映射问题

问题描述 投票:0回答:2

考虑到this post所描述的设计模式,这里是example view model:

final class SayHelloViewModel: ViewModelType {
    let input: Input
    let output: Output

    struct Input {
        let name: AnyObserver<String>
        let validate: AnyObserver<Void>
    }

    struct Output {
        let greeting: Driver<String>
    }

    private let nameSubject = ReplaySubject<String>.create(bufferSize: 1)
    private let validateSubject = PublishSubject<Void>()

    init() {
        let greeting = validateSubject
            .withLatestFrom(nameSubject)
            .map { name in
                return "Hello \(name)!"
            }
            .asDriver(onErrorJustReturn: ":-(")

        self.output = Output(greeting: greeting)
        self.input = Input(name: nameSubject.asObserver(), validate: validateSubject.asObserver())
    }
}

以上似乎是一个完美的设计模式。我唯一的问题是,当您从nameSubject-> greeting的映射函数比此处显示的复杂得多,而需要抽象到它自己的函数中时,会发生什么?

在以下情况下,我已经将映射功能抽象为它自己的名为sayHello.的函数。当然,现在的问题是,我们在初始化self之前先引用self。如何在非平凡的示例中保持这种设计模式?

final class SayHelloViewModel {
    let input: Input
    let output: Output

    struct Input {
        let name: AnyObserver<String>
        let validate: AnyObserver<Void>
    }

    struct Output {
        let greeting: Driver<String>
    }

    private let nameSubject = ReplaySubject<String>.create(bufferSize: 1)
    private let validateSubject = PublishSubject<Void>()

    init() {
        let greeting = validateSubject
            .withLatestFrom(nameSubject)
            .map(sayHello)
            .asDriver(onErrorJustReturn: ":-(")
        self.output = Output(greeting: greeting)
        self.input = Input(name: nameSubject.asObserver(), validate: validateSubject.asObserver())
    }

    private func sayHello(name: String) -> String {
        return "Hello \(name)!"
    }
}
swift reactive-programming rx-swift
2个回答
1
投票

只需将您的映射函数设为私有自由函数,而不是类成员。仅在需要访问成员时才需要成为成员本身,这种情况下这种可能性很小。


0
投票

还提出了另一种可能的解决方案

final class SayHelloViewModel {
    private let disposeBag = DisposeBag()

    let input: Input
    let output: Output

    struct Input {
        let name: AnyObserver<String>
        let validate: AnyObserver<Void>
    }

    struct Output {
        let greeting: Driver<String>
    }


    init() {
        let nameSubject = ReplaySubject<String>.create(bufferSize: 1)
        let validateSubject = PublishSubject<Void>()
        let greeting = PublishSubject<String>()

        output = Output(greeting: greeting.asDriver(onErrorJustReturn: ":-("))
        input = Input(name: nameSubject.asObserver(), validate: validateSubject.asObserver())

        validateSubject
            .withLatestFrom(nameSubject)
            .map(sayHello)
            .bind(to: greeting)
            .disposed(by: disposeBag)
    }

    private func sayHello(name: String) -> String {
        return "Hello \(name)!"
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.