我已经将 ViewModels 引入到我最新的 iOS 应用程序中,但我在一些地方遇到了困难。想知道这里是否有人可以向我发送正确的方向。
基本上,应该如何/在哪里处理导航和错误对话框。
例如,目前我有一个注册过程,它由一个 RegistrationViewController 和一个 RegistrationViewModel 组成。当在 UI 中点击注册按钮时,会在 RegistrationViewModel 上调用注册方法。即来自 Controller 的 viewModel.register()
问题1:导航应该如何处理?
成功完成对 Web 服务的注册调用后,应用程序应根据某些业务逻辑导航到多个屏幕之一。目前,我通过调用导航管理器类在 ViewModel 中处理此问题。 Navigator.goToSuccessScreen()。这可以接受吗?我觉得这应该在 Controller 内部而不是通过 ViewModel 处理,但是所有用于确定导航到何处的业务逻辑都将在 View Controller 中完成。
问题2:如何显示错误对话框?
可以说上面的注册调用失败了。并且 UI 需要向用户显示 UIAlertView。可以调用 Navigator.displayError("some or other error message") 吗?还是应该再次将其路由回 Controller 以显示消息本身?
最佳答案
您可以使用路由枚举来处理它,并使其在 ViewModel 中可观察:
enum MoviesListViewModelRoute {
case initial
case showMovieDetail(title: String, overview: String, posterPlaceholderImage: Data?, posterPath: String?)
}
final class DefaultMoviesListViewModel: MoviesListViewModel {
// MARK: - OUTPUT
let route: Observable<MoviesListViewModelRoute> = Observable(.initial)
...
func didSelect(item: MoviesListItemViewModel) {
route.value = .showMovieDetail(title: item.title,
overview: item.overview,
posterPlaceholderImage: item.posterImage.value,
posterPath: item.posterPath)
}
从 View(viewController) 观察路由值并在值更改时显示它:final class MoviesListViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
bind(to: viewModel)
viewModel.viewDidLoad()
}
private func bind(to viewModel: MoviesListViewModel) {
viewModel.route.observe(on: self) { [weak self] in
self?.handle($0)
}
}
}
extension MoviesListViewController {
func handle(_ route: MoviesListViewModelRoute) {
switch route {
case .initial: break
case .showMovieDetail(let title, let overview, let posterPlaceholderImage, let posterPath):
let vc = moviesListViewControllersFactory.makeMoviesDetailsViewController(title: title,
overview: overview,
posterPlaceholderImage: posterPlaceholderImage,
posterPath: posterPath)
navigationController?.pushViewController(vc, animated: true)
}
}
}
关于ios - 使用 MVVM 时如何在 iOS 中处理导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34673087/