简体   繁体   English

MVVM + RXSwift+ Coordinator 如何设置数据?

[英]MVVM + RXSwift+ Coordinator how to set data?

Good night?晚安? Can you tell me how can I write data from controller 2 to controller 1. I have a coordinate at the main screen.你能告诉我如何将数据从 controller 2 写入 controller 1。我在主屏幕上有一个坐标。

final class MenuCoffeLikeCoordinator: TabBarPresentableCoordinator {

var tabBarItem: UITabBarItem = {
    let title = "Меню"
    let image = UIImage(asset: Resources.Assets.TabBarItems.mainTabBar)
    let selectedImage = UIImage(asset: Resources.Assets.TabBarItems.mainTabBarSelected)
    let item = UITabBarItem(title: title, image: image, selectedImage: selectedImage)
    return item
}()

var navigationController: UINavigationController

init(navigationController: UINavigationController = UINavigationController()) {
    self.navigationController = navigationController
}

var didFinish: (() -> Void)?

func start() {
    self.navigationController.pushViewController(createMenuCoffeLikeFlow(), animated: true)
}

func stop() {}

func createMenuCoffeLikeFlow() { -> UIViewController {
    let menuController = MenuCoffeLikeAssembler.createModule()
    
    menuController.rx.didTapMapLayer.onNext {
        let controller = self.createCoffeeBarMap()
        self.navigationController.pushViewController(controller, animated: true)
    }
    
    return menuController
}
private func createCoffeeBarMap() -> UIViewController {
    let controller = CoffeeBarContainerAssembler.createModule()
    controller.obsRelay.subscribe(onNext: { event in
        self.navigationController.popViewController(animated: true)
    })
    return controller
}

} }

In the createMenuCoffeLikeFlow function, I create the main screen, and when I click on the button, I go to screen 2 (createCoffeeBarMap)在 createMenuCoffeLikeFlow function 中,我创建了主屏幕,当我点击按钮时,我 go 到屏幕 2 (createCoffeeBarMap)

Inside the function (createCoffeeBarMap), I subscribe to the PublishSubject, and when the data changes, I get a new text.在 function (createCoffeeBarMap) 里面,我订阅了 PublishSubject,当数据发生变化时,我得到一个新的文本。 I need to write this text in the menuCoffeeControler which is in the createMenuCoffeLikeFlow function.我需要在 createMenuCoffeeLikeFlow function 中的 menuCoffeeControler 中编写此文本。 How can i do this?我怎样才能做到这一点?

Here's how I would implement it using my Cause Logic Effect (CLE) architecture.以下是我将如何使用我的原因逻辑效果 (CLE) 架构来实现它。 With CLE you don't need to implement a Coordinator because a reusable Coordinator class already exists in the library.使用 CLE,您不需要实现协调器,因为库中已经存在可重用的协调器 class。 This means less code for you to write.这意味着您可以编写更少的代码。

Unlike yours, this sample is complete and will compile.与您的不同,此示例是完整的并且可以编译。 The only thing missing is the creation and layout of the views inside the view controllers.唯一缺少的是视图控制器内视图的创建和布局。

import Cause_Logic_Effect
import RxCocoa
import RxSwift
import UIKit

/// This function produces the view controller that is attached to your tab bar controller. I don't put the
/// `UITabBarItem` in here. Instead I attach that when connecting to the tab bar controller.
func menuCoffeLikeTab() -> UIViewController {
    // the `configure` function calls its closure inside the viewDidLoad method.
    let menuController = MenuController().configure { $0.connect() }
    let controller = UINavigationController(rootViewController: menuController)
    return controller
}

/// It depends on how you want to layout your view controllers on whether anything else goes in here. If you
/// use storyboards, then add `@IBOutlet` before the views here. If you create your views programatically
/// then add a `loadView()` override.
final class MenuController: UIViewController {
    var mapLayerButton: UIButton!
    var textField: UITextField!
    let disposeBag = DisposeBag()
}

extension MenuController {
    func connect() {
        // This is the meat. The `coffeeBarResponse` observable pushes the
        // CoffeeBarController onto the navigation stack when approprate and
        // then emits any values produced by it. Notice how this looks alot like
        // a network call except you are querying the user instead of the server.
        let coffeeBarResponse = mapLayerButton.rx.tap
            .flatMapFirst(pushScene(on: navigationController!, animated: true) {
                CoffeeBarController().scene { $0.connect() }
            })
            .share()
        // The pushScene function above will create a coordinator for the
        // CoffeeBarController. When needed, the coordinator will create the
        // view controller, call its `connect` and emit any values from that.
        // When the Observable completes, the coordinator will pop the view
        // controller off.

        coffeeBarResponse
            .bind(to: textField.rx.text)
            .disposed(by: disposeBag)
    }
}

final class CoffeeBarController: UIViewController {
    var saveButton: UIButton!
    var textField: UITextField!
}

extension CoffeeBarController {
    func connect() -> Observable<String> {
        // when the user taps the save button, this will emit whatever value is
        // in the text field and then complete the observable.
        saveButton.rx.tap
            .withLatestFrom(textField.rx.text.orEmpty)
            .take(1)
    }
}

Like I said above, this uses a reusable Coordinator class that is part of the library instead of you having to write your own all the time.就像我上面所说的,这使用了一个可重用的协调器 class,它是库的一部分,而不是你必须一直编写自己的。 This architecture will significantly reduce the amount of boilerplate code you have to write.这种架构将显着减少您必须编写的样板代码量。 Learn more at https://github.com/danielt1263/CLE-Architecture-Tools and join the RxSwift Slack to learn more about RxSwift in general.https://github.com/danielt1263/CLE-Architecture-Tools了解更多信息并加入 RxSwift Slack 以了解更多关于 RxSwift 的一般信息。

this is a typical scenario where DI comes to rescue.这是 DI 来救援的典型场景。 You have to have some kind of a shared container which will register and resolve dependencies.你必须有某种共享容器来registerresolve依赖关系。 I use Dip https://github.com/AliSoftware/Dip.git and here is an example with your code.我使用Dip https://github.com/AliSoftware/Dip.git ,这是您的代码示例。 The idea is the following - you register closure in one VC and pass it to another.这个想法如下 - 你在一个 VC 中注册闭包并将其传递给另一个。

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

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