我有以下观点:
struct Menu: View {
let sctions:[TestSection] = [
TestSection(id: 0, name: "One", items: [
ListItem(id: 0, name: "1"),
ListItem(id: 1, name: "2"),
ListItem(id: 2, name: "3"),
ListItem(id: 3, name: "4")
]),
TestSection(id: 1, name: "Two", items: [
ListItem(id: 4, name: "4"),
ListItem(id: 5, name: "5"),
ListItem(id: 6, name: "6"),
ListItem(id: 7, name: "7")
]),
TestSection(id: 2, name: "Three", items: [
ListItem(id: 8, name: "8"),
ListItem(id: 9, name: "9"),
])
]
var body: some View {
NavigationView {
List {
ForEach(sctions) { section in
Section(header: Text(section.name)) {
ForEach(section.items) { item in
TestCell(item: item)
}
}
}
}
.listStyle(.plain)
.navigationBarTitle("Title")
}
}
}
struct TestCell: View {
@ObservedObject private var model:ItemModel
let item:ListItem
init(item:ListItem) {
self.item = item
self.model = ItemModel(itemId:item.id)
}
var body: some View {
Text("item: \(item.name)")
}
}
class ItemModel:ObservableObject {
@Published var someProperty:Int
let itemId:Int
init(itemId:Int) {
self.itemId = itemId
self.someProperty = 0
}
}
我正在尝试从模型层的角度决定如何在 SwiftUI 中处理子视图。
子视图中的一个选项是 @ObservedObject
。父级创建模型并将其设置在子级上,或者父级在子级上传递一个属性,然后允许子级在其初始值设定项中初始化模型:
init(item:ListItem) {
self.item = item
self.model = ItemModel(itemId:item.id). // <<---- HERE
}
然后看看这个,我想知道这是否比在子视图中使用 @StateObject
来管理其模型的生命周期低。
然后我尝试了这个:
struct TestCell: View {
@StateObject var model = ItemModel() // <<-- error "Missing argument for parameter 'itemId' in call"
let item:ListItem
var body: some View {
Text("item: \(item.name)")
}
}
哪个,显然显示错误:
我不确定在使用 ItemModel
方法时如何在 TestCell
中初始化 @StateObject
。
我的问题是:
在这种类型的场景中,我希望每个单元格都有自己的模型(处理模型相关的逻辑,如进行网络调用、更新模型层等...)我应该创建当我在创建单元格期间在父级中实例化单元格并将其设置在单元格 (@ObservedObject
) 上时建模?
或者一个单元应该使用 @StateObject
作为它的模型,如果是这样,我如何让模型在需要参数时正确地初始化自己,例如 let itemId:Int
?
答案 0 :(得分:0)
不推荐您的第一个选项,因为
init(item:ListItem) {
self.item = item
self.model = ItemModel(itemId:item.id). // <<---- HERE
}
<块引用>
在视图中创建观察对象是不安全的
https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app
您会在 SO 中找到许多关于 View
不可靠的问题。你还会发现那些告诉人们这样做的人,但你会发现它有问题。
如果您使用 @StateObject var model: ItemModel = ItemModel()
,这是 Apple 在 ObservableObject
中创建 View
的唯一例外
然后切换
let itemId:Int
在您的 ItemModel
中
var itemId:Int = 0
然后在 TestCell
中添加到最外面的 View
.onAppear(){
model.itemId = item.id
}
或者根据您的 ParentView 及其 ViewModel,您可以在 ObservableObject
ViewModel 中创建 class
并将其作为参数传递给
@ObservedObject private var model:ItemModel
重要的是,解决方法考虑到不应在 ObservableObject
中创建 View
,@StateObject
除外。 SwiftUI 保留在认为有必要时重新创建任何 View
的权利。