【问题标题】:SwiftUI where to load data in MVVMSwiftUI 在哪里加载 MVVM 中的数据
【发布时间】:2020-05-10 22:54:31
【问题描述】:

我有一个名为Requests 的视图,它有一个名为RequestViewModel 的视图模型。该视图模型将Request 类型的模型作为参数,然后它为视图提供了几种方法。问题是我需要先从 firebase 加载这些 requests 但我不知道在哪里。

视图模型是获取数据的好地方吗,因为我觉得它不是?对于其他视图模型,我也有类似的情况;对于前PackageViewModel 和更多...

我应该在 Service 中的其他地方为 ex 加载这些数据,然后将其传递给这个视图模型,还是有其他方法可以做到这一点?

class RequestViewModel: ObservableObject {
    @Published var request: Request
    @Published var requests: [Request] = []

    init(request: Request) {
        self.request = request
    }

    func loadRequests() -> Void {
        network call here {
            self.requests = requests
        }
    } 
}

【问题讨论】:

    标签: ios swift mvvm swiftui swift5


    【解决方案1】:

    使用专用网络服务。

    搜索你的感受,你知道这是真的。

    问题是,它与您认为您对 MVVM 了解的所有内容背道而驰。

    大多数 MVVM 开发人员使用视图模型作为网络请求(具有副作用)、业务逻辑和视图控件的便捷包装器。

    其背后的想法是重构视图绑定模型和相关的逻辑/效果。

    与所有设计模式一样,一些开发人员会滥用它、扭曲它、从 java 复制和粘贴它……等等。

    随着时间的推移,开发者开始认为 ViewModel 是理所当然的,既然它是 Android 的规范,它必须在 iOS 中工作,对吧?

    任何称职的开发人员在尝试将 MVVM 移植到 SwiftUI 时都会问这些问题:

    • SwiftUI 中有绑定机制吗?它是如何工作的?

    • struct Model: View {...},这是模型-视图映射吗?如果是这样,我可能不需要声明 一个单独的视图模型? (专业问题)

    • 任何符合 ObservableObject 的人都可以被观察到(触发视图更新),这样 超出了视图模型的狭义定义(视图相关的属性)。可观察对象 可以是服务共享资源。例如。;网络服务。恭喜你 刚刚迈出了进入更大世界的第一步。

    • 我为什么要引入引用类型视图模型来扩充值类型模型视图 在围绕值类型构建的 SDK 中符合 View 的每个此类值类型?斯威夫特不是 爪哇?

    现在我们有足够的设置来正确回答您的问题。

    1. 创建一个专用的网络服务,例如;

      final class Resource: ObservableObject { // don't even need inheritance, OOP isn't always the best solution in all situations 
          @Published var requests = [Requests]()
          // publish other resources
          func loadRequests() {
              /* update requests in callback */
          }
      }
      
    2. 使用它,例如;

      struct Model: View {
          @State var model = MyModel() // can be "view model", because it maps to view 
          @EnvironmentObject var res: Resource
          // or as an alternative, @ObservedObject var res = Resource()
          var body: some View {
              // access the automatic binding provided by SwiftUI, e.g.; res.requests
              // call res.loadRequests() to mutate internal state of a reference type
              // note that stateful part of the "view model" is refactored out 
              // so that `model` can be value type, yet it provides binding via @State
              // instead of ObservableObject, which has to be reference type
              // this is the brilliance of SwiftUI, it moves heaven and earth so you have 
              // the safety of immutability from value type, **unlike MVVM**
          }  
      }  
      
    3. 完成。

    4. 为什么我们又需要 ViewModel? 请在 cmets 中告诉我。

    【讨论】:

    • 我很感兴趣,但是你有一个完整的工作代码示例吗?我已经阅读了您的几篇文章,但我很难看到它们在实践中是如何结合在一起的。
    【解决方案2】:

    这真的取决于。您是否仅将数据用于这一视图?还是您在整个应用程序中都使用它?

    仅用于此视图的数据

    ViewModel 获取数据没问题。以repo 为例。

    请注意,存储在 ObservableObject 中的数据不会持久保存。因此,您必须将ViewModel 作为@State 存储在父视图中。看here

    要为整个应用持久化的数据

    然后我建议使用.environmentObject() 将某种“存储”加载到您的视图中。以repo 为例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-27
      • 2010-11-24
      • 2010-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      相关资源
      最近更新 更多