假设你有一些对象的列表--比如说猫。有一个公共视图模型,用于存储从服务器接收到的猫的数据。视图上的每个元素都是一只猫的一小部分数据。在此扇区内,用户可以更改数据。如何正确链接猫列表的视图模型和一只猫的视图模型?
struct Cat : Identifiable {
let id = UUID()
var name: String
var breed: String
}
struct CatListView : View {
@ObservedObject private(set) var viewModel: ViewModel
var body: some View {
List(self.viewModel.items) { (item) in
CatView(viewModel: self.viewModel.createViewModel(item: item))
}
}
}
extension CatListView {
class ViewModel : ObservableObject {
@Published var items: [Cat]
init(items: [Cat]) {
self._items = .init(initialValue: items)
}
public func createViewModel(item: Cat) -> CatView.ViewModel {
.init(data: item)
}
}
}
struct CatView : View {
@ObservedObject private(set) var viewModel: ViewModel
var body: some View {
VStack {
TextField("Name", text: self.$viewModel.data.name)
TextField("Breed", text: self.$viewModel.data.breed)
}
}
}
extension CatView {
class ViewModel : ObservableObject {
@Published var data: Cat
init(data: Cat) {
self._data = .init(initialValue: data)
}
}
}如何正确地将更改从CatView.ViewModel转移到CatListView.ViewModel?绑定可能吗?但我认为这是View和View之间联系的一种变体。也许这个选项是正确的?
extension CatListView {
class ViewModel : ObservableObject {
@Published private(set) var items: [Cat]
private var cancelItems: [Int: AnyCancellable] = [:]
init(items: [Cat]) {
self._items = .init(initialValue: items)
}
public func createViewModel(item: Cat) -> CatView.ViewModel {
let model: CatView.ViewModel = .init(data: item)
if let index = self.items.firstIndex(where: { $0.id == item.id }) {
self.cancelItems[index] = model.$data
.dropFirst()
.removeDuplicates()
.sink {
self.items[index] = $0
}
}
return model
}
}
}发布于 2021-04-28 01:25:17
您必须管理以下项目:
猫列表模型: single cat Model
struct Cat: Identifiable, Hashable {
let id = UUID()
var name: String
var colorDescription: String
}class CatsModel: ObservableObject {
@Published var catsBag: [Cat]
init() {
// Fetch here the cats from your server
}
// CRUD cicle
func create(_ cat: Cat) { ... }
func update(_ cat: Cat) { ... }
func delete(_ cat: Cat) { ... }
}struct CatsList: View {
@StateObject var catsModel = CatsModel()
var body: some View {
List {
ForEach(catsModel.catsBag.indices, id: \.self) { catIndice in
CatCell(cat: $catsModel.catsBag[catIndice])
}
}
}
}struct CatCell: View {
@Binding var cat: Cat
var body: some View {
TextField("The cat name is: ", text: $cat.name)
.padding()
}
}在这一点上,你会意识到,如果你删除列表中的最后一只猫,应用程序就会崩溃。这可能是SwiftUI错误,您可以在此处找到解决方案:https://www.swiftbysundell.com/articles/bindable-swiftui-list-elements/
https://stackoverflow.com/questions/67286852
复制相似问题