【问题标题】:Where to trigger Loading in Clean Architeture Swift在 Clean Architecture Swift 中触发加载的位置
【发布时间】:2019-11-15 22:20:36
【问题描述】:

我应该将触发加载的代码放置在我的应用中显示的正确位置。

这样做是正确的吗?因为它在屏幕上显示一些东西,所以它适合作为 UI 逻辑

class ViewController: UIViewController {
 func fetchData() {
     showLoading()
     interactor?.fetchData()
 }
}

还是在交互器上?因为这是一个业务逻辑。例如,每次发出请求时,我们都应该显示加载。 View 只知道如何构造加载,而不知道何时显示。

class Interactor {
   func fetchData() {
     presenter?.presentLoading(true)
     worker?.fetchData() { (data) [weak self] in
          presenter?.presentLoading(false)
          self?.presenter?.presentData(data)
     }
   }
}

同样的问题适用于 MVVM 和 MVP。

【问题讨论】:

  • 由于Interactor独立于任何视图逻辑,并且Presenter负责准备/处理UI,因此最好通过Presenter控制加载视图。因此,您应该创建用于在视图中显示和隐藏加载视图的函数,并在需要时从演示者调用它。 MVP 或 MVVM 也是如此。
  • 但是只有在我的数据完成获取时才会调用演示者。甚至不再需要显示加载了
  • 如何触发Interactor中的数据获取?它是由演示者调用还是由其他事件调用?
  • 在worker上获取数据

标签: ios swift design-patterns mvvm clean-architecture


【解决方案1】:

这完全取决于你。我正在使用 Observable 显示加载。 在我的 viewModel 中有一个名为 action 的枚举:

enum action {
    case success(count:Int)
    case deleteSuccess
    case loading
    case error
}

和一个动作类型的 Observable :

var actionsObservable = PublishSubject<action>()

然后,在获取数据之前,我调用 actionObservable(loading) 的 onNext 方法

并在 viewController 中订阅它:

vm.actionsObserver
    .observeOn(MainScheduler.instance)
    .subscribe(onNext: { (action) in
        switch action {
        case .success(let count):
     if(count == 0){
                self.noItemLabel.isHidden = false
            }
            else{
            self.noItemLabel.isHidden = true
            }
            self.refreshControl.endRefreshing()
            self.removeSpinner()
        case .loading:
            self.showSpinner(onView : self.view)
        case .error:
            self.removeSpinner()

        }
    }, onError: { (e) in
        print(e)
    }).disposed(by: disposeBag)

【讨论】:

    【解决方案2】:

    您可以使用委托或完成处理程序从视图模型更新 UI。

    class PaymentViewController: UIViewController {
    // for UI update
    func showLoading() {
            self.showLoader()
       }
        
        func stopLoading() {
            self.removeLoader()
        }
    }
    
    protocol PaymentOptionsDelegate : AnyObject {
        func showLoading()
        func stopLoading()
    }
    
    class PaymentOptionsViewModel {
       weak var delegate : PaymentOptionsDelegate?
    
    func fetchData() {
        delegate?.showLoading()
        delegate?.stopLoading()
    }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2018-01-03
      • 2017-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 2020-06-18
      • 1970-01-01
      相关资源
      最近更新 更多