【问题标题】:SwiftUI - Passing a variable to Observable ObjectSwiftUI - 将变量传递给可观察对象
【发布时间】:2020-07-07 03:34:51
【问题描述】:

我有一个从前一个视图接收 ID 值的视图。我还需要获取该 ID 值并将其传递给 ObservableObject,以便我可以对该 ID 运行 Firestore 查询。我不知道如何为我的 ObservableObject 获取该 ID。

struct ItemView: View {
   var itemName: String
   var itemID: String
   @ObservedObject var items = getItemsData()
   // ..... etc
   }


 class getItemsData() {
    @Published var data = [items]()
    init() {
       let db = Firestore.firestore()
       db.collection("items").whereField("itemID", isEqualTo: *THIS IS WHERE I NEED THE ITEMID *),addSnapshotListner {(snap, err) in ...
}

所以在查询调用中,我需要调用 ItemID 值以根据视图顶部定义的值进行查询。

【问题讨论】:

    标签: firebase google-cloud-firestore swiftui


    【解决方案1】:

    我认为你的 getItemsData 类应该继承自 ObservableObject

    class GetItemsData: ObservableObject {...}
    

    要将 itemId 获取到您的 GetItemsData 实例中,您可以将参数添加到您的 init()

    class GetItemsData: ObservableObject {
        init(itemId: String) {
            ...
        }
    }
    

    }

    要将这一切联系在一起,您有两个选择。您可以向 ItemView 添加一个初始化,例如:

    struct ItemView: View {
        let itemName: String
        let itemModel: GetItemsData
        init(itemName: String, itemID: String) {
            self.itemName = itemName
            itemModel = GetItemsData(itemId: itemID)
        }
    }
    

    我更喜欢将可观察对象传递到视图中,因此它更像是 MVVM 中的视图模型

    struct ItemView: View {
        let itemName: String
        let itemModel: GetItemsData
    

    【讨论】:

    • SwiftUI 视图不应初始化对象,除非您的属性将它们包装起来,否则它们会丢失,因为视图结构不会留下来
    【解决方案2】:

    如果您的 ObservableObject 有任何状态或不在顶级视图中,@tomcully 方式最终会在每个父视图更新时实例化它。

    而且如果你在init()里面调用一个api,你会做很多不必要的api调用。

    你可以这样做:

    struct ItemView: View {
       let itemName: String
       let itemID: String
       @StateObject var itemsLoader = ItemsLoader()
       var body: some View {
         ...
         ForEach(itemsLoader.items) {
         ...
        .onAppear {
          itemsLoader.load(itemID)
        }
      }
    }
    class ItemsLoader: ObservedObject {
        let db = Firestore.firestore()
        @Published var items: [Item] = []
        var itemID: String = ""
        
        func load(_ id: String) {
            if itemID != id {
                itemID = id
                db.collection("items").whereField("itemID", isEqualTo: itemID),addSnapshotListner {(snap, err) in ...
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 2019-01-24
      • 1970-01-01
      • 2014-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多