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)
    }
}