Kebanyakan contoh MVVM yang telah saya kerjakan memiliki penerapan ModelINotifyPropertyChanged
, tetapi dalam contoh CommandSink Josh Smith mengimplementasikan ViewModelINotifyPropertyChanged
.
Saya masih secara kognitif menyusun konsep MVVM, jadi saya tidak tahu apakah:
- Anda harus meletakkan
INotifyPropertyChanged
di ViewModel untuk mulaiCommandSink
bekerja - Ini hanyalah penyimpangan dari norma dan itu tidak terlalu penting
- Anda harus selalu menerapkan Model
INotifyPropertyChanged
dan ini hanyalah kesalahan yang akan diperbaiki jika ini dikembangkan dari contoh kode ke aplikasi
Apa pengalaman orang lain tentang proyek MVVM yang telah Anda kerjakan?
c#
mvvm
inotifypropertychanged
Edward Tanguay
sumber
sumber
Jawaban:
Saya akan mengatakan sebaliknya, saya selalu memakai
INotifyPropertyChanged
ViewModel saya - Anda benar-benar tidak ingin mencemari model Anda dengan fitur spesifik WPF sepertiINotifyPropertyChanged
, barang-barang itu harus berada di ViewModel.Saya yakin orang lain akan tidak setuju, tetapi itulah cara saya bekerja.
sumber
Saya sangat tidak setuju dengan konsep bahwa Model seharusnya tidak menerapkan
INotifyPropertyChanged
. Antarmuka ini bukan khusus UI! Ini hanya menginformasikan perubahan. Memang, WPF banyak menggunakan ini untuk mengidentifikasi perubahan, tetapi itu tidak berarti itu adalah antarmuka UI. Saya akan membandingkannya dengan komentar berikut: " Ban adalah aksesori mobil ". Tentu saja, tetapi sepeda, bus, dll juga menggunakannya. Singkatnya, jangan menganggap antarmuka itu sebagai hal UI.Karena itu, itu tidak berarti saya percaya bahwa Model harus memberikan pemberitahuan. Bahkan, sebagai aturan praktis, model tidak harus mengimplementasikan antarmuka ini, kecuali jika diperlukan.Dalam kebanyakan kasus di mana tidak ada data server didorong ke aplikasi klien, modelnya bisa basi. Tetapi jika mendengarkan data pasar keuangan, maka saya tidak melihat mengapa model tidak dapat mengimplementasikan antarmuka. Sebagai contoh, bagaimana jika saya memiliki logika non-UI seperti layanan yang ketika menerima tawaran atau harga Permintaan untuk nilai yang diberikan itu mengeluarkan peringatan (mis. Melalui email) atau memesan? Ini bisa menjadi solusi bersih yang mungkin.
Namun, ada berbagai cara untuk mencapai hal-hal, tetapi saya selalu berdebat demi kesederhanaan dan menghindari redundansi.
Apa yang lebih baik Mendefinisikan peristiwa pada koleksi atau perubahan properti pada model tampilan dan menyebarkannya ke model atau meminta tampilan memperbarui model secara intrinsik (melalui model tampilan)?
Intinya setiap kali Anda melihat seseorang mengklaim bahwa " Anda tidak dapat melakukan ini atau itu " itu adalah tanda mereka tidak tahu apa yang mereka bicarakan.
Itu benar-benar tergantung pada kasus Anda dan pada kenyataannya MVVM adalah kerangka kerja dengan banyak masalah dan saya belum melihat implementasi umum MVVM di seluruh papan.
Saya berharap saya memiliki lebih banyak waktu untuk menjelaskan banyak rasa MVVM dan beberapa solusi untuk masalah umum - kebanyakan disediakan oleh pengembang lain, tapi saya rasa saya harus melakukannya lain kali.
sumber
INotifyPropertyChanged
adalah bagian dariSystem.ComponentModel
namespace yang untuk " perilaku run-time dan desain-waktu komponen dan kontrol ". JANGAN GUNAKANINotifyPropertyChanged
dalam Model, hanya di ViewModels. Tautan ke dokumen: docs.microsoft.com/en-us/dotnet/api/system.componentmodelDalam MV-VM, ViewModel selalu (Model tidak selalu) mengimplementasikan
INotifyPropertyChanged
Lihatlah MV-VM Project Template / Toolkit dari http://blogs.msdn.com/llobo/archive/2009/05/01/download-mv-vm-project-template-toolkit.aspx . Ini menggunakan perintah
DelegateCommand
for dan harus menjadi template awal yang bagus untuk Anda proyek MV-VM.sumber
Saya pikir MVVM sangat buruk namanya dan memanggil ViewModel a ViewModel menyebabkan banyak orang kehilangan fitur penting dari arsitektur yang dirancang dengan baik, yang merupakan DataController yang mengontrol data tidak peduli siapa pun yang mencoba menyentuhnya.
Jika Anda menganggap View-Model lebih sebagai DataController dan mengimplementasikan arsitektur di mana DataController Anda adalah satu-satunya item yang menyentuh data, maka Anda tidak akan pernah menyentuh data secara langsung, tetapi selalu menggunakan DataController. DataController berguna untuk UI tetapi tidak hanya untuk UI. Ini untuk lapisan bisnis, lapisan UI, dll ...
Anda berakhir dengan model seperti ini. Bahkan bisnis hanya boleh menyentuh data menggunakan ViewModel. Maka teka-teki Anda hilang begitu saja.
sumber
Itu tergantung pada bagaimana Anda menerapkan model Anda. Perusahaan saya menggunakan objek bisnis yang mirip dengan objek CSLA Lhotka dan memanfaatkan secara luas
INotifyPropertyChanged
seluruh model bisnis.Mesin validasi kami sangat bergantung pada pemberitahuan bahwa properti berubah melalui mekanisme ini dan bekerja dengan sangat baik. Jelas, jika Anda menggunakan implementasi berbeda selain objek bisnis di mana pemberitahuan perubahan tidak begitu penting untuk operasi, Anda mungkin memiliki metode lain untuk mendeteksi perubahan dalam model bisnis Anda.
Kami juga memiliki Model Tampilan yang menyebarkan perubahan dari Model jika diperlukan, tetapi Model Tampilan sendiri mendengarkan perubahan Model yang mendasarinya.
sumber
Saya setuju dengan jawaban Paulo, menerapkan
INotifyPropertyChanged
dalam Model benar-benar dapat diterima dan bahkan disarankan oleh Microsoft -Meskipun itu terserah Anda untuk memutuskan apakah Anda ingin jenis implementasi atau tidak, tapi ingat -
Diambil dari - http://msdn.microsoft.com/en-us/library/gg405484(PandP.40).aspx
Saya telah bekerja di beberapa proyek di mana kami belum menerapkan
INotifyPropertyChanged
dalam model kami dan karena ini kami menghadapi banyak masalah; duplikasi properti yang tidak perlu diperlukan dalam VM dan pada saat yang sama kami harus memperbarui objek yang mendasarinya (dengan nilai yang diperbarui) sebelum meneruskannya ke BL / DL.Anda akan menghadapi masalah secara khusus jika Anda perlu bekerja dengan koleksi objek model Anda (misalnya dalam kisi atau daftar yang dapat diedit) atau model yang kompleks; objek model tidak akan diperbarui secara otomatis dan Anda harus mengelola semua itu di VM Anda.
sumber
Tetapi kadang-kadang (seperti dalam teks tautan presentasi ini ) model adalah layanan, yang memasok aplikasi dengan beberapa data online dan kemudian Anda perlu memastikan pemberitahuan bahwa data baru tiba atau data telah berubah menggunakan acara ...
sumber
Saya pikir jawabannya cukup jelas jika Anda ingin mematuhi MV-VM.
lihat: http://msdn.microsoft.com/en-us/library/gg405484(v=PandP.40).aspx
Dalam pola MVVM, tampilan merangkum UI dan logika UI apa pun, model tampilan merangkum logika dan status presentasi, dan model merangkum logika bisnis dan data.
sumber
Saya akan katakan di ViewModel Anda. Ini bukan bagian dari Model karena Model ini agnostik UI. Model harus 'semuanya KECUALI bisnis agnostik'
sumber
Menerapkan INPC dalam model dapat digunakan jika model secara jelas terbuka di ViewModel. Tetapi secara umum, ViewModel membungkus model adalah kelasnya sendiri untuk mengurangi kompleksitas model (yang seharusnya tidak berguna untuk penjilidan). Dalam hal ini, INPC harus diimplementasikan dalam ViewModel.
sumber
Saya menggunakan
INotifyPropertyChange
antarmuka dalam model. Sebenarnya, perubahan properti model harus dipecat oleh UI atau klien eksternal saja.Saya perhatikan beberapa kelebihan dan kekurangan:
Keuntungan
Notifier ada dalam model bisnis
Kekurangan
Model ini memiliki properti (qty, rate, komisi, totalfrieght). Totalfrieght dihitung menggunakan qty, rate, perubahan komisi.
Pada memuat nilai dari db, perhitungan total frieght disebut 3 kali (qty, rate, komisi). Itu harus sekali.
Jika nilai, qty ditugaskan di lapisan bisnis, lagi-lagi pemberi tahu disebut.
Seharusnya ada opsi untuk menonaktifkan ini, mungkin di kelas dasar. Namun, pengembang bisa lupa melakukan ini.
sumber
Saya pikir itu semua tergantung pada use case.
Ketika Anda memiliki model sederhana dengan banyak properti, Anda dapat menerapkannya dengan INPC. Secara sederhana saya maksudkan bahwa model ini terlihat seperti POCO .
Jika model Anda lebih kompleks dan menggunakan domain model interaktif - model referensi model, berlangganan acara model lain - menerapkan model acara sebagai INPC adalah mimpi buruk.
Tempatkan diri Anda pada posisi beberapa entitas model yang harus berkolaborasi dengan beberapa model lainnya. Anda memiliki berbagai acara untuk berlangganan. Semuanya diimplementasikan sebagai INPC. Bayangkan event handler yang Anda miliki. Satu kaskade besar jika-klausa dan / atau beralih klausa.
Masalah lain dengan INPC. Anda harus merancang aplikasi Anda untuk mengandalkan abstraksi, bukan implementasi. Ini biasanya dilakukan dengan menggunakan antarmuka.
Mari kita lihat 2 implementasi berbeda dari abstraksi yang sama:
Sekarang lihat keduanya. Apa yang dikatakan IConnectionManagerINPC kepada Anda? Bahwa beberapa propertinya dapat berubah. Anda tidak tahu yang mana dari mereka. Bahkan desainnya hanya perubahan IsConnected, karena sisanya hanya baca-saja.
Sebaliknya, niat IConnectionManager jelas: "Saya dapat memberi tahu Anda bahwa nilai properti IsConnected saya dapat berubah".
sumber
Cukup gunakan
INotifyPropertyChange
di viewmodel Anda dan bukan di Model,model biasanya menggunakan
IDataErrorInfo
untuk menangani kesalahan validasi jadi tetap di ViewModel Anda dan Anda benar di jalan MVVM Anda.sumber
Misalkan referensi objek dalam tampilan Anda berubah. Bagaimana Anda akan memberi tahu semua properti agar diperbarui untuk menunjukkan nilai yang benar? Memanggil
OnPropertyChanged
dalam pandangan Anda untuk semua properti objek adalah sampah bagi sudut pandang saya.Jadi yang saya lakukan adalah membiarkan objek itu sendiri untuk memberi tahu siapa pun ketika nilai dalam properti berubah, dan dalam pandangan saya, saya menggunakan binding seperti
Object.Property1
,Object.Property2
dan seterusnya . Dengan cara itu jika saya hanya ingin mengubah objek yang saat ini dipertahankan dalam pandangan saya, saya hanya melakukannyaOnPropertyChanged("Object")
.Untuk menghindari ratusan pemberitahuan selama pemuatan objek, saya memiliki indikator boolean pribadi yang saya atur menjadi true selama pemuatan yang diperiksa dari objek
OnPropertyChanged
dan tidak melakukan apa pun.sumber
Biasanya ViewModel akan mengimplementasikan
INotifyPropertyChanged
. Model dapat berupa apa saja (file xml, basis data atau bahkan objek). Model digunakan untuk memberikan data ke viewmodel, yang menyebar ke tampilan.Lihat disini
sumber
imho saya pikir mengimplementasikan
INotifyPropertyChange
model viewmodel dan dapat menggunakan notifikasi pada "level" yang berbeda.mis. dengan beberapa layanan dokumen dan objek dokumen Anda memiliki acara DocumentChanged yang viewmodel mendengarkan untuk menghapus dan membangun kembali view. Dalam model tampilan edit Anda memiliki pertukaran properti untuk properti dokumen untuk mendukung tampilan. Jika layanan ini sangat membantu dengan menyimpan dokumen (memperbarui tanggal perubahan, pengguna terakhir, dan sebagainya), Anda dengan mudah mendapatkan kelebihan acara Ipropertychanged dan hanya perubahan dokumen saja sudah cukup.
Tetapi jika Anda menggunakan
INotifyPropertyChange
dalam model Anda, saya pikir itu adalah praktik yang baik untuk menyampaikannya di viewmodel Anda sebagai ganti berlangganan secara langsung dalam pandangan Anda. Dalam hal ini ketika peristiwa berubah dalam model Anda, Anda hanya perlu mengubah model tampilan dan tampilan tetap tidak tersentuh.sumber
Semua properti, yang terikat pada pandangan saya, ada di dalam ViewModel saya. Jadi mereka harus mengimplementasikan antarmuka INotifyPropertyChanged. Oleh karena itu, View mendapatkan semua perubahan.
[Menggunakan toolkit MVVM Light, saya membiarkan mereka mewarisi dari ViewModelBase.]
Model memegang logika bisnis, tetapi tidak ada hubungannya dengan pandangan. Jadi tidak perlu untuk antarmuka INotifyPropertyChanged.
sumber