我有一个ObservableObject-Class,在该类中,我得到了一个名为 persons 的已发布变量!我确实使用一些名为 allData 的数据对其进行了初始化。
然后,我尝试使用按钮操作更新 allData ,此操作将所需的更新应用于我的 allData ,但是我发布的var不知道此数据已更新!
如何使发布的内容能够看到新的更新的 allData ?
struct PersonData: Identifiable {
let id = UUID()
var name: String
}
var allData = [PersonData(name: "Bob"), PersonData(name: "Nik"), PersonData(name: "Tak"), PersonData(name: "Sed"), PersonData(name: "Ted")]
class PersonDataModel: ObservableObject {
@Published var persones: [PersonData] = allData
}
struct ContentView: View {
@StateObject var personDataModel = PersonDataModel()
var body: some View {
VStack
{
Button("update allData") { allData = [PersonData(name: "Bob")] }
HStack
{
ForEach(personDataModel.persones) { person in Text(person.name) }
}
}
.font(Font.title)
}
}
PS:我不想为此使用.onChange或其他东西,我希望这在我的班级内部发生。
我也知道我可以使用下来的代码来完成这项工作,但这不是答案
personDataModel.persones = [PersonData(name: "Bob")]
答案 0 :(得分:1)
拥有一个顶级属性(在任何类或结构之外)可能不是一个好主意。我看不到全部图片,但看来您的应用需要全局状态(例如,在@StateObject
级别初始化的App
)。考虑以下答案:
如果您确实需要观察数组,则需要使其成为 observable 。
一种选择是使用Combine
框架中的CurrentValueSubject:
var persons = ["Bob", "Nik", "Tak", "Sed", "Ted"].map(PersonData.init)
var allData = CurrentValueSubject<[PersonData], Never>(persons)
class PersonDataModel: ObservableObject {
@Published var persones: [PersonData] = allData.value
private var cancellables = Set<AnyCancellable>()
init() {
allData
.sink { [weak self] in
self?.persones = $0
}
.store(in: &cancellables)
}
}
struct ContentView: View {
@StateObject var personDataModel = PersonDataModel()
var body: some View {
VStack {
Button("update allData") {
allData.send([PersonData(name: "Bob")])
}
HStack {
ForEach(personDataModel.persones) { person in
Text(person.name)
}
}
}
.font(Font.title)
}
}
答案 1 :(得分:0)
allData
在初始化时被复制到persones
中,因此之后对其进行更改对personDataModel
无效。创建StateObject
之后,您必须像
Button("update allData") {
self.personDataModel.persones = [PersonData(name: "Bob")]
}
答案 2 :(得分:0)
我认为您做错了事。
如果要更新所有视图,则必须使用@EnviromentObject
传递同一对象。
我不知道您的存储方法(JSON,CORE DATA,iCloud),但是正确的方法是直接更新模型
class PersonDataModel: ObservableObject
{
@Published var persones: [PersonData] = loadFromJSON //one func that is loading your object stored as JSON file
func updateAllData() {
storeToJSON(persones) //one func that is storing your object as JSON file
}
}
struct ContentView: View {
@StateObject var personDataModel = PersonDataModel()
var body: some View {
VStack
{
Button("update allData") {
self.personDataModel.persones = [PersonData(name: "Bob")]
}
HStack
{
ForEach(personDataModel.persones) { person in Text(person.name) }
}
}
.font(Font.title)
.onChange($personDataModel.persones) {
persones.updateAllData()
}
}
}