[英]SwiftUI: How to initialize a new StateObject in a parent view?
[英]Unable to initialize @StateObject ViewModel in SwiftUI
我試圖在 ViewModel 中注入 managedObjectContext 並且由於某種奇怪的原因它拋出了一個奇怪的錯誤。
struct ContentView: View {
@Environment(\.managedObjectContext) var viewContext
@StateObject var addBudgetVM: AddBudgetViewModel
init() {
// THIS LINE CAUSES ISSUES
addBudgetVM = AddBudgetViewModel(context: viewContext)
}
var body: some View {
// some code here
}
}
Cannot assign to property: 'addBudgetVM' is a get-only property
這里是 AddBudgetViewModel 的實現
import Foundation
import CoreData
class AddBudgetViewModel: ObservableObject {
@Published var name: String = ""
var context: NSManagedObjectContext
init(context: NSManagedObjectContext) {
self.context = context
}
func save() {
}
}
您可以在沒有參數的情況下初始化視圖模型,並在視圖模型內部聲明 de environment
struct ContentView: View {
@StateObject var addBudgetVM: AddBudgetViewModel = AddBudgetViewModel()
var body: some View {
// some code here
}
}
視圖模型:
class AddBudgetViewModel: ObservableObject {
@Published var name: String = ""
@Environment(\.managedObjectContext) var viewContext
func save() {
}
}
我發現最好的方法是從超級視圖注入視圖模型。 這很好地將使用視圖模型的視圖與創建視圖模型分開。 它提高了可測試性,因為它可以輕松注入模擬視圖模型。
就像是:
struct ParentView: View {
@Environment(\.managedObjectContext) var viewContext
var body: some View {
//...
AddBudgetView(viewModel: AddBudgetViewModel(context: viewContext))
//...
}
}
struct AddBudgetView: View {
viewModel: AddBudgetViewModel
var body: some View {
// ...
}
}
class AddBudgetViewModel: ObservableObject {
private (set) var context: NSManagedObjectContext
init(context: NSManagedObjectContext) {
self.context = context
}
func save() {
}
}
我什至可能不會在視圖模型中包含 Core Data 代碼。 我會將所有這些放在一個主模型中,並將主模型實例傳遞給視圖模型初始化程序而不是托管對象上下文。 然后視圖模型可以調用主模型上的方法來創建和保存項目。 通過這種方式,您的視圖模型與存儲實現細節隔離開來,您可以對存儲進行更改,例如替換核心數據,而無需到處觸摸視圖模型。
您需要像這樣實例化StateObject
:
_addBudgetVM = StateObject(wrappedValue: AddBudgetViewModel(context: viewContext))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.