【问题标题】:Computed Property from Child Struct Not Updating in SwiftUISwiftUI 中子结构的计算属性未更新
【发布时间】:2021-10-16 04:45:38
【问题描述】:

我的 SwiftUI 应用中有一个数据模型,看起来像这样:

struct Entry: Identifiable{
  var id = UUID().uuidString
  var name = ""

  var duration: Int{
    //An SQLite query that returns the total of the "duration" column
    let total = try! dbc.scalar(tableFlight.filter(db.entry == id).select(db.duration.total))
    return Int(total)
  }
}

struct Flight: Identifiable{
  var id = UUID().uuidString
  var duration = 0
  var entry: String?
}

我有一个ObservableObject 视图模型,它生成如下条目:

class EntryModel: ObservableObject{
  static let shared = EntryModel()
  @Published var entries = [Entry]()

  init(){
    get()
  }

  func get(){
    //Stuff to fetch the entries
    entries = //SQLite query that returns an array of Entry objects
  }
}

最后,在我的View 中,我列出了所有条目名称及其关联的duration,如下所示:

ForEach(modelEntry.entries){ entry in
  VStack{
    Text(entry.name) //<-- Updates fine
    Text(entry.duration) //<-- Gets set initially, but no updates
  }
}

我遇到的问题是,当我为 Entry 更新 Flight 时,我认为 duration 不会更新。我知道这不会发生,因为只有 entries 会在更改时重绘。

但即使我在EntryModel 中手动调用get() 函数,关联的duration 仍然不会更新。

有没有更好的方法来做到这一点?如何让父元素的计算属性在其子元素更新时重新计算?

【问题讨论】:

  • get() 之后调用objectWillChange.send() 怎么样?我不确定这是否可行,但值得一试——至少它会向 View 发出尝试更新的信号。
  • 我不明白的是,您的持续时间甚至不是来自您的入门模型中的任何内容。那么你到底在你的入门模型中更新了什么?因为 dbc 不在您的模型中。我只能假设(并且担心)它是某种全局变量(或者你使用小写的类来混淆读者)。
  • duration属性下的注释所示,这是一个返回相关数据的SQLite查询。 dbc 是一个数据库单例。不过,这与手头的问题并不真正相关。
  • 抱歉,这只是反值类型编码。值类型不应该有这样的隐藏依赖关系,特别是如果在不同的时间点使用,它的行为会有所不同。那最好是一个全局函数,或者更好的是,它是暴露dbc 依赖项的类的一部分。
  • 我明白了。不要那样做。它会伤害你。将该查询放入初始化程序中。每次重新渲染视图时都会运行您的查询,不仅仅是为了描述,而是为了任何目的。

标签: swift swiftui combine observableobject


【解决方案1】:

我想通了。我的实际代码在ForEach 中使用了一个孩子View,其中VStack 是。我只是将entry 传递给它,所以这些值只是最初设置的,因此没有反应。

通过将 entry 更改为 Binding,它正在工作:

ForEach($modelEntry.entries){ $entry in
  ChildView(entry: $entry)
}

请注意,$modelEntry 上的 $ 和返回 $entryXcode 13+ 功能(但向后兼容 iOS 14 和 macOS 11.0)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    • 2020-08-11
    • 2014-03-01
    • 2019-10-03
    • 2017-07-29
    • 2019-12-08
    相关资源
    最近更新 更多