简体   繁体   English

RxSwift变量组成,无需订阅/绑定/驱动

[英]RxSwift Variable composition without subscribe/bind/drive

I need some internal state in a viewModel but also trying to follow the "no subscription / bind / drive / ..." ideal approach and only compose between Observables . 我需要在viewModel中有一些内部状态,但也要尝试遵循“无订阅/绑定/驱动器/ ...”的理想方法,并且只能在Observables之间进行Observables

How can I specify what a Variable observes? 如何指定Variable观测值?

Example: 例:

private var userProfilesToFetch = Variable<[String]>([])
private var users: Variable<[User]> {

    return //something that observes fetchUserProfiles() and when it emits, appends to its .value
}

private func fetchUserProfiles() -> Observable<User?> {

    let reference = databaseRef.child("users")

    return userProfilesToFetch.asObservable()
        .filter({ $0 != [] })
        .map({ $0.last! })
        .flatMap({ (userId) -> Observable<User?> in

            return self.service.observeAllChildren(of: reference.child(userId), by: .value)
                .map({ (snapshot) -> User? in

                        guard let values = snapshot.value as? [String: AnyObject] else { return nil }

                        var user = User(dictionary: values)

                        user.id = snapshot.key

                        return user
                })
        })
} 

The "ideal approach" is to avoid the use of Subjects/Variables. “理想方法”是避免使用主题/变量。 Instead, favor sequence emitters (functions that return an observable,) sequence receivers (functions that accept an observable as a parameter,) and sequence transformers (functions that do both.) 取而代之的是,偏爱序列发射器(返回可观察到的函数),序列接收器(接受可观察到的函数作为参数)和序列转换器(两者都执行的函数)。

Sequence emitters and receivers necessarily perform side effects and inside a sequence receiver, there is necessarily a subscribe/bind in order to unpack the value and use it. 序列发射器和接收器必然会产生副作用,并且序列接收器内部 ,必须有一个订阅/绑定才能拆开值并使用它。

There should be a direct and obvious link between the emitters and receivers. 发射器和接收器之间应该有直接明显的联系。 Subjects/Variables tend to break that link. 主题/变量倾向于破坏该链接。

In this ideal approach, your "view model" is not a class/struct containing a bunch of variables. 在这种理想的方法中,您的“视图模型”不是包含一堆变量的类/结构。 Your view model is a function that takes observables as parameters and returns observables for the view controller to bind to. 您的视图模型是一个函数,将可观察值作为参数并返回可观察值以供视图控制器绑定。 For example: 例如:

class MyViewController: UIViewController {
    @IBOutlet weak var name: UITextView!
    @IBOutlet weak var label: UILabel!

    override
    func viewDidLoad() {
        super.viewDidLoad()
        let viewModel = myViewModel(name: name.rx.text.orEmpty)
        viewModel.label.bind(to: label.rx.text).disposed(by: bag)
    }
    let bag = DisposeBag()
}

struct MyViewModel { 
    let label: Observable<String>
}

// this function could be turned into an `init` method on the MyViewModel struct if you would prefer.
fun myViewModel(name: Observable<String>) -> MyViewModel {
    let label = name.map { "Hello \($0)!" }
    return MyViewModel(label: label)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM