Haruskah kita mengikat tampilan ke properti model atau ViewModel harus memiliki itu sendiri ..?

21

Saya memulai proyek dengan lingkungan teknis berikut:. Net 4.0, Entity Framework 4.0, WPF dengan Arsitektur MVVM

Saya melihat banyak contoh di internet, beberapa buku dengan lingkungan ini. Dalam beberapa contoh penulis memiliki Ide ini:

  1. Viemodel akan memiliki instance kelas Model (Entity Framework Entity eg Person)
  2. Ikat kontrol tampilan WPF ke properti Model

Sementara beberapa penulis melakukannya:

  1. Viemodel akan memaparkan semua properti model.
  2. Ikat kontrol tampilan WPF ke properti ViewModel daripada langsung ke model.

Jadi apakah itu ide yang baik untuk membiarkan tampilan mengikat properti dari model daripada viewmodel mengekspos sendiri? Atau yang lebih disukai?

Pravin Patil
sumber
Secara pribadi saya menemukan mengekspos properti model untuk menghasilkan pemisahan yang baik dari lapisan data dan lapisan logika Anda.
Alex Hope O'Connor

Jawaban:

25

Saya pikir banyak programmer pertama kali mencoba untuk mengambil jalan pintas dari pengikatan langsung ke model, tetapi dalam pengalaman saya ini memiliki beberapa kelemahan utama. Masalah utama adalah bahwa jika model entitas Anda dipertahankan oleh NHibernate atau serupa, maka segera setelah Lihat memperbarui properti model, maka NHibernate dapat bertahan perubahan itu ke database. Itu tidak berfungsi dengan baik untuk layar edit yang memiliki tombol Simpan / Batalkan. Pada kenyataannya, mungkin memilih untuk menunggu dan bertahan semuanya sebagai batch, tetapi idenya adalah ketika Anda mengubah model, Anda melakukan perubahan Anda.

Jadi, Anda masih bisa lolos dengan mengikat langsung ke model properti pada layar read-only, tetapi kemudian Anda akan memiliki inkonsistensi.

Selain itu, sebagian besar model tidak diimplementasikan INotifyPropertyChangedsehingga mungkin tidak sesuai target pengikatan jika keadaan layar berubah setelah tampilan awal.

Mengingat kemudahan properti-otomatis, saya sarankan selalu mengikat View ke ViewModel, bukan ke Model. Ini konsisten, sederhana, dan memberi Anda fleksibilitas paling untuk mendukung perubahan di masa depan.

Scott Whitlock
sumber
Saya suka jawaban Anda. +1 untuk menyebutkan Edit / Simpan Layar .. Tapi kemudian akan sulit untuk menulis properti dua kali - sekali dalam model dan lagi dalam tampilan-model. Itu juga akan meningkatkan waktu pengembangan. Apakah menurut Anda dibenarkan untuk melakukannya ...?
Pravin Patil
9
@Pravin Patil - fwiw, setiap kali saya mengambil jalan pintas itu, saya kemudian mengutuk diri sendiri ketika saya harus kembali dan memperbaikinya. Ada sedikit upaya untuk mengimplementasikan kembali properti di ViewModel, terutama jika itu hanya baca (karena Anda dapat menggunakan properti yang diimplementasikan secara otomatis dengan setter pribadi). Faktanya adalah, dalam banyak kasus Model adalah struktur data yang berbeda dari ViewModel. Beri Anda fleksibilitas untuk mengubah Model tanpa memengaruhi Tampilan. Semakin sedikit Anda harus mengubah tampilan, semakin baik, karena tampilan sulit untuk diuji.
Scott Whitlock
4
@Scott Whitlock: Saya telah mengembangkan aplikasi WPF dengan NHibernate selama dua tahun sekarang dan tidak pernah memiliki masalah apa pun yang mengikat langsung ke model. Bahkan, ketika properti model berubah, sebagian besar upaya yang sama untuk perubahan, terlepas dari apa yang Anda terikat. Dan ketika saya benar-benar perlu melakukan beberapa routing di ViewModel itu sendiri di kemudian hari, maka itu tidak layak untuk menginvestasikan waktu sebelum saya membutuhkannya. Saya mengikuti pendekatan YAGNI (belum) dan tidak mengalami kesulitan. Saya pikir Anda dan yang lainnya di sini menjadi sedikit dogmatis tentang masalah ini.
Falcon
16

Intinya ViewModeladalah bahwa itu adalah model dari View.

Anda harus mengikat ViewModelke View, bukan Modelproperti apa pun (tidak secara langsung, bagaimanapun).

Oded
sumber
8

Saya menemukan kedua metode ini dapat diterima

Mengikat hanya ke ViewModel adalah pendekatan "MVVM-purist" dan mengarah pada pemisahan antar lapisan yang lebih baik. Mengikat ke Model biasanya lebih cepat dan lebih nyaman.

Kecuali saya memiliki alasan yang baik untuk sepenuhnya memisahkan lapisan (ukuran proyek, masalah pemeliharaan di masa depan, jenis Model yang saya kerjakan, dll), saya mengikat Model.

Rachel
sumber
7

Saya pikir apa yang Anda lihat adalah sebuah konsep yang disebut bind through, yaitu jika model Anda memiliki properti bernama nama dan view-model Anda mengekspos properti ini tanpa pengeditan atau konversi tambahan maka Anda dapat mengikat melalui model sehingga akan menjadi.

Kode semu:

 {Binding: MyViewModel.MyModel.Name}

Hal ini dilakukan untuk mengurangi jumlah properti 'Fluff' pada model tampilan, sayangnya itu juga merupakan ide yang buruk dalam jangka panjang. Konsep model tampilan adalah untuk memastikan bahwa tampilan tidak bergantung pada model. Dengan mengikat Anda sekarang harus memastikan bahwa model Anda berisi properti bernama nama jika tidak implementasi Anda akan rusak.

Jika Anda hanya mengikat sejauh model tampilan, Anda dapat mengganti model dan tampilan tidak akan pernah tahu karena hanya akan pernah melihat properti bernama Nama pada model tampilan.

Sekarang ini dapat dikurangi dalam keadaan tertentu jika model Anda didasarkan pada antarmuka. Jadi, jika antarmuka memiliki IBaseDetails yang mengekspos properti ModuleName maka Anda bisa:

Kode semu:

 {Binding: MyViewModel.MyModel.ModuleName}

Selama salah satu Model yang Anda buat memenuhi antarmuka IBaseDetails, emas Anda, perlu diketahui bahwa ini adalah kasus tepi dan secara umum Anda 90% selalu lebih baik untuk membungkus model tampilan Anda di sekitar model yang dicakupnya.

DeanMc
sumber
2

Jika Anda melihat banyak gesekan mencoba keluar dari Model -> ViewModel, coba sesuatu seperti AutoMapper. Ini menghapus kebosanan yang terkait dengan menyalin properti secara manual.

Bryan Boettcher
sumber
1

Saya sampai di sini hanya karena saya memiliki keraguan yang sama dan saya yakin bahwa saya akan selalu terikat untuk melihat model daripada model.

Ambil pendekatan Angular Reactive Form. Anda membuat grup formulir menggunakan beberapa informasi Model Tampilan tetapi kemudian Anda harus mengakses formulir. Nilai untuk mendapatkan nilai dan menyalin nilai ke model menggunakan auto mapper atau manual apa pun. Saya pikir tidak ada yang lebih indah daripada mengikat ke properti dalam model tampilan, katakanlah misalnya saya memiliki halaman tampilan proyek di mana saya memiliki nama proyek, nama klien, dll.

Ada hubungan antara proyek dan klien karena proyek memiliki klien. Jadi pada level ini, saya seharusnya tidak peduli tentang hubungan itu. Saya hanya perlu memperlihatkan secara visual nama proyek dan nama klien dalam tampilan, jadi saya menempatkan 2 properti dalam model tampilan nama proyek dan nama klien sehingga saya mengikat kontrol tampilan ke kedua mereka, nanti saya akan khawatir tentang memberikan nilai ke properti-properti dalam kode di belakang mengambil lalu dari struktur apa pun yang dimiliki model.

Hal yang sama bisa untuk memperbarui model dalam hal save / cancel tidak ada yang lebih bersih.

Ivan Carmenates García
sumber
posting ini agak sulit dibaca (dinding teks). Maukah Anda mengeditnya menjadi bentuk yang lebih baik?
nyamuk
Ini dia, Ceria.
Ivan Carmenates García