【问题标题】:RxSwift: MVVM Update Struct on View Model and Trigger Table Update on View ControllerRxSwift:视图模型上的 MVVM 更新结构和视图控制器上的触发器表更新
【发布时间】:2019-01-30 14:49:44
【问题描述】:

我目前正在深入研究 RxSwift,我正在尝试使用它来更新 ViewController(.xib) 上的 TableView,其中包含我从 JSON 获得并使用 Codable 编码到结构中的数据。

这是我的虚拟机自动取款机:

import Foundation
import RxCocoa
import RxSwift

protocol MenuViewModelProtocol {
    func viewDidLoad()
}

class MenuViewModel: MenuViewModelProtocol {

    private (set) var menu = MenuModel()
    private let menuIntermediary = MenuDataIntermediary()

    func viewDidLoad() {
        debugPrint("MenuViewModel.viewDidLoad: Async request for menu was made")
        requestAndSetMenuToIntermediary { (_ success) in
            switch success {
            case true:
                debugPrint("MenuViewModel.requestAndSetMenuToIntermediary: Did get Menu successfully")
                // print(self.menu) // -> menu is here
            case false:
                debugPrint("MenuViewModel.requestAndSetMenuToIntermediary: Did not get Menu successfully")
            }
        }
    }

    private func requestAndSetMenuToIntermediary(completion: @escaping (_ success: Bool) -> Void) {
        menuIntermediary.jsonDataToMenuConversion { [weak self] (success) in
            DispatchQueue.global().async {
                guard let strongSelf = self else {
                    debugPrint("MenuViewModel.requestMenuToIntermediary: couldn't create a strong self reference")
                    completion(false)
                    return
                }

                guard let menu = menu else {
                    debugPrint("MenuViewModel.requestMenuToIntermediary: couldn't unwrap menu data")
                    completion(false)
                    return
                }
                strongSelf.menu = menu

                // print(strongSelf.menu) // -> menu is here
                completion(true)
            }
        }
    }
}

requestAndSetMenuToIntermediary 的流程简而言之:

-> DataManager 从 URL 请求 JSON 并返回一个 Data?

-> 中间层使用 Codable 将 JSON 解析为 Struct(带有嵌套结构)并返回 Struct?

-> ViewModel 获取 Struct?并打开它,为 UI 设置做好准备。

-> ??

我在'??'的问题是通知 VC menu 已更新,以便设置 TableView。有什么建议么?我尝试过使用 PublishSubjects、BehaviorSubject 和 observables,但我似乎无法让它工作。我怀疑它是语法还是与后台流程相关的东西......

提前致谢! P.s - 如果需要更多信息,我可以很高兴地提供它,我只是想不发很长的帖子:p

【问题讨论】:

  • 就目前而言,您的代码无法编译我不知道menu 应该是MenuModel? 还是MenuModel。如果我将其设为非可选,那么您的 guard let menu = menu 将无法编译,因为您无法打开非可选的包装;如果我将其设为可选,则同一行将失败,因为缺少 self

标签: json swift asynchronous tableview rx-swift


【解决方案1】:

我在您的代码中没有找到任何关于数据绑定的代码。通常,如果您使用 RxSwift,您应该创建一个数据序列并绑定到您的视图。对于表格视图或集合视图,我们喜欢使用RxDataSource

  1. 创建一个Observable 从服务器获取响应
  2. 使用map 转换数据
  3. 将数据绑定到您的视图

在你的情况下,你应该定义一个函数来从服务器获取菜单模型

private func getMenuModel() -> Obserable<MenuModel> {
   /* the code getting response from server and transform to menu model */
}

声明一个 Observable

let menuModelObservable: Observable<MenuModel>

init() {
   menuModelObservable = getMenuModel()
}

将数据绑定到您的TableView

/* Your ViewController*/

override func viewDidLoad() {
    super.viewDidLoad()
    let viewModel = MenuViewModel()
    viewModel.menuModelObservable.bind(to: tableView.rx.items(cellIdentifier: "Cell")) { index, model, cell in
      cell.textLabel?.text = model
    }.disposed(by: disposeBag)
}

【讨论】:

  • 感谢您的回答!事实上,我在每个选项的 sn-p 中没有任何与 Rx 相关的代码,因为自从我尝试使用 PublishSubjects 和 ObjectRelays/ObjectSubject 以及其他没有成功的 shannanigans 以来,这有点混乱。我会试试这个并很快回复你:)
猜你喜欢
  • 1970-01-01
  • 2015-09-30
  • 2023-03-18
  • 1970-01-01
  • 2015-02-10
  • 1970-01-01
  • 2017-11-13
  • 1970-01-01
  • 2018-06-30
相关资源
最近更新 更多