Section 4/131 menit
4. @Bindable — Dua Arah Binding
4. @Bindable — Dua Arah Binding
Ketika kita butuh $viewModel.propertyName (binding untuk TextField, Toggle, dll) dari @Observable object, gunakan @Bindable.
swift
@Observable
final class SettingsViewModel {
var notificationsEnabled: Bool = true
var username: String = ""
var selectedTheme: Theme = .system
}
struct SettingsView: View {
// @State untuk ownership (view ini yang memiliki viewModel)
@State private var viewModel = SettingsViewModel()
var body: some View {
Form {
Toggle("Notifikasi", isOn: $viewModel.notificationsEnabled)
// $viewModel.notificationsEnabled bekerja langsung karena
// @State sudah menyediakan Bindable access.
}
}
}
// Ketika viewModel datang dari luar (tidak di-own oleh view ini):
struct SettingsSheet: View {
// @Bindable membuat kita bisa membuat Binding ke property @Observable object
// yang datang sebagai parameter (bukan @State).
@Bindable var viewModel: SettingsViewModel
var body: some View {
Form {
TextField("Username", text: $viewModel.username) // binding ke username
Picker("Tema", selection: $viewModel.selectedTheme) { // binding ke selectedTheme
ForEach(Theme.allCases) { theme in
Text(theme.name).tag(theme)
}
}
}
}
}
Kapan @Bindable diperlukan:
| Skenario | Cara |
|---|---|
View memiliki viewModel (@State) |
Gunakan $viewModel.property langsung |
| viewModel datang dari parameter | Gunakan @Bindable var viewModel lalu $viewModel.property |
viewModel dari @Environment |
Ambil dengan @Environment, lalu buat @Bindable lokal |
swift
// @Environment + @Bindable
struct AccountView: View {
@Environment(AccountViewModel.self) private var account
var body: some View {
// Buat @Bindable lokal dari environment value
@Bindable var account = account
TextField("Nama", text: $account.displayName)
}
}