SwiftUI将数据传递到ViewModel

时间:2020-08-28 07:27:49

标签: swiftui

我试图将要传递到视图中的数据放入ViewModel中。

我看到了很多关于从外部来源(如Json或Firebase)检索数据的教程,但与使用从上一页传递的数据无关。

我必须对数据进行大量计算才能获得最终输出。

在这里,我需要“进入” ShowViewModel。

struct ShowView: View {
  
    @ObservedObject var entry:EntryData
 
    var showVM = ShowViewModel()
 
    var body: some View {
   
       Text("\(entrybeg)")
    
    }
}

我只是在玩一个空白的ViewModel进行测试。

class ShowViewModel: ObservableObject {

    @Published var test = "something"
    @Published var m:Month = Month()

}

非常感谢您!

3 个答案:

答案 0 :(得分:2)

SwiftUI不使用“视图模型”模式,它使用“视图”结构告诉系统如何创建屏幕上显示的实际视图。但是,您可以将相关属性分组为自己的结构,以便将对任何属性的更改检测为对结构本身的更改。在父视图中使用@State创建它,并在子视图中使用@Binding在$语法中将其引用。 @State将监视它的变化并重新计算主体,类似于ObservableObject@Published,这将重新计算使用该数据的子视图的主体。

struct ShowViewConfig {
    var test = "something"
    var m:Month = Month()

    // you can even put a method in to update it
    mutating func fetch(name:String, ascending: Bool){
    }
}

然后在您的ContentView中创建它,如下所示:

struct ContentView {
    @State var config = ShowViewConfig()
     var body: some View {
          ...
          ShowView(config:$config)

然后像下面这样在ShowView中使用它:

struct ShowView: View {
    @Binding var config : ShowViewConfig
    var body: some View {
       Text("\(config.test)")
    }
}

您可以在Data Essentials in SwiftUI WWDC 2020的8:44看到这种模式

enter image description here

如果您有一个模型对象,即受@ObservableObject监视,那么您的工作就是将层次结构中某个位置的View结构中的丰富数据类型转换为简单数据类型,并在必要时使用格式化程序。您可以在WWDC 2020 Structure your app for SwiftUI previews @ 11:22中了解更多信息。因此,您可以看到是否尝试在View Model对象而不是View结构中执行此操作,那是错误的方法。

enter image description here

答案 1 :(得分:1)

您可以尝试以下操作:

struct ShowView: View {
    @ObservedObject var entry: EntryData

    @ObservedObject var showVM: ShowViewModel // declare only (@ObservedObject optionally)
    
    init(entry: EntryData) {
        self.entry = entry
        self.showVM = ShowViewModel(entry: entry)
    }

    var body: some View {
        Text("\(entrybeg)")
    }
}

class ShowViewModel: ObservableObject {
    @Published var test = "something"
    @Published var m: Month = Month()
    
    private var entry: EntryData
    
    init(entry: EntryData) {
        self.entry = entry
    }
}

现在,当您创建视图时,需要将EntryData传递给它:

ShowView(entry: EntryData())

答案 2 :(得分:1)

我在这里假设您有一个进行计算的类。此外,ShowViewModel需要该计算的结果。我会做以下事情:

class EntryData: ObservableObject {
    @Published var calculation = 42
}

struct ShowView: View {
    @ObservedObject var showVM: ShowViewModel
    
    var body: some View {
        Text("\(showVM.m.daysRequired)")
    }
    
    init(entryData: EntryData) {
        let month = ShowViewModel.Month(daysRequired: entryData.calculation)
        self.showVM = ShowViewModel(month: month)
    }
}

class ShowViewModel: ObservableObject {
    struct Month {
        let daysRequired: Int
    }

    @Published var test = "something"
    @Published var m: Month
    
    init(month: Month) {
        self.m = month
    }
}

struct ContentView: View {
    var body: some View {
        ShowView(entryData: EntryData())
    }
}