RxSwift 中的 RACChannel 相当于什么?

发布于 2025-01-16 12:35:04 字数 102 浏览 1 评论 0原文

我想进行从 UIViewController 到 VewModel 的单向绑定,在 ReactiveObjC 中我使用了 RACChannel。 后一个的等效项是什么,或者最好的方法是什么?

I want to make one-way binding from UIViewController to VewModel, in ReactiveObjC I've used RACChannel.
What is the equivalent of a later one or what is the best way to do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痴情换悲伤 2025-01-23 12:35:04

我必须在这里回答更普遍的问题。将视图控制器绑定到视图模型。

这是一个关于反应式视图模型的精彩视频。

构造良好的反应式视图模型是一个单一函数,需要多个 Observable来自视图输入的输入并返回一些绑定到用于输出的视图的 Observables。

一个简单的示例登录视图模型...

func login(
    callServer: @escaping (URLRequest) -> Observable<Data>,
    email: Observable<String>,
    password: Observable<String>,
    login: Observable<Void>
) -> (
    loggedIn: Observable<Void>,
    errorMessage: Observable<String>
) {
    let loginResponse = login
        .withLatestFrom(
            Observable.combineLatest(email, password) { makeLoginURLRequest(email: $0, password: $1) }
        )
        .flatMapLatest {
            callServer($0)
                .map { try JSONDecoder().decode(LoginResponse.self, from: $0) }
                .materialize()
        }
    
    let loggedIn = loginResponse
        .compactMap { $0.element != nil ? () : .none }
    
    let errorMessage = loginResponse
        .compactMap { $0.error?.localizedDescription }
    
    return (
        loggedIn: loggedIn,
        errorMessage: errorMessage
    )
}

在视图控制器的 viewDidLoad 中调用它,如下所示:

let (loggedIn, errorMessage) = login(
    callServer: URLSession.shared.rx.data(request:),
    email: emailTextField.rx.text.orEmpty.asObservable(),
    password: passwordTextField.rx.text.orEmpty.asObservable(),
    login: loginButton.rx.tap.asObservable()
)

loggedIn
    .bind(onNext: { print("user is now logged in!") })
    .disposed(by: disposeBag)

errorMessage
    .bind(onNext: { print("display error message", $0) })
    .disposed(by: disposeBag)

最后,如果您不喜欢使用元组,可以用结构替换它们。

I'm going to have to answer the more general question here. That of binding the view controller to the view model.

Here's a good video for Reactive View Models

A well constructed reactive view model is a single function that takes a number of Observable inputs from the view inputs and returns a number of Observables that are bound to the views meant for output.

A simple example login view model...

func login(
    callServer: @escaping (URLRequest) -> Observable<Data>,
    email: Observable<String>,
    password: Observable<String>,
    login: Observable<Void>
) -> (
    loggedIn: Observable<Void>,
    errorMessage: Observable<String>
) {
    let loginResponse = login
        .withLatestFrom(
            Observable.combineLatest(email, password) { makeLoginURLRequest(email: $0, password: $1) }
        )
        .flatMapLatest {
            callServer($0)
                .map { try JSONDecoder().decode(LoginResponse.self, from: $0) }
                .materialize()
        }
    
    let loggedIn = loginResponse
        .compactMap { $0.element != nil ? () : .none }
    
    let errorMessage = loginResponse
        .compactMap { $0.error?.localizedDescription }
    
    return (
        loggedIn: loggedIn,
        errorMessage: errorMessage
    )
}

Call it in the view controller's viewDidLoad like this:

let (loggedIn, errorMessage) = login(
    callServer: URLSession.shared.rx.data(request:),
    email: emailTextField.rx.text.orEmpty.asObservable(),
    password: passwordTextField.rx.text.orEmpty.asObservable(),
    login: loginButton.rx.tap.asObservable()
)

loggedIn
    .bind(onNext: { print("user is now logged in!") })
    .disposed(by: disposeBag)

errorMessage
    .bind(onNext: { print("display error message", $0) })
    .disposed(by: disposeBag)

Lastly, if you don't like using tuples, you can replace them with structs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文