RxMVVM использует входы / выходы и проблемы со сложным отображением - PullRequest
0 голосов
/ 05 февраля 2020

Учитывая шаблон дизайна, как описано в этом посте , вот пример модели :

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)!"
    }
}

1 Ответ

1 голос
/ 05 февраля 2020

Просто сделайте вашу функцию отображения частной свободной функцией вместо члена класса. Он должен быть самим членом, только если ему нужен доступ к членам, что в этом шаблоне крайне маловероятно.

Редактировать: Также вы могли бы очистить это, избегая предметов и воздействуя непосредственно на входы / выходы. вот так:

final struct SayHelloViewModel {

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

    // An output
    let greeting: Driver<String>

    init(inputs: Input) {
        let greeting = input.validate
            .withLatestFrom(input.name)
            .map(sayHello)
            .asDriver(onErrorJustReturn: ":-(")
    }
}

private func sayHello(name: String) -> String {
    return "Hello \(name)!"
}

Вы могли бы пойти еще дальше и вообще не использовать структуру / класс и сделать ее просто функцией, которая возвращает кортеж / структуру выходных данных.

...