뷰를 모델 속성에 바인딩해야합니까 아니면 ViewModel에 고유 한 속성이 있어야합니까?


21

.Net 4.0, Entity Framework 4.0, MVVM Architecture가 포함 된 WPF와 같은 기술 환경에서 프로젝트를 시작하고 있습니다.

나는 인터넷에서 많은 예제를 보았습니다.이 환경의 일부 책. 일부 예제에서 저자는 다음과 같은 아이디어를 가지고있었습니다.

  1. Viemodel은 Model 클래스 (Entity Framework Entity 예 : Person)의 인스턴스를 갖습니다.
  2. WPF 뷰 컨트롤을 모델의 속성에 바인딩

일부 저자는 :

  1. Viemodel은 모델의 모든 속성을 노출합니다.
  2. WPF 뷰 컨트롤을 모델이 아닌 ViewModel의 속성에 바인딩합니다.

그래서 viewmodel이 자체적으로 노출시키는 것이 아니라 model이 속성을 바인딩하도록하는 것이 좋은 생각입니까? 아니면 어느 것이 더 선호됩니까?


개인적으로 모델의 속성을 노출시켜 데이터 계층과 논리 계층을 적절하게 분리합니다.
Alex Hope O'Connor

답변:


25

많은 프로그래머가 먼저 모델에 직접 바인딩하는 바로 가기를 시도한다고 생각하지만 내 경험상 이것은 몇 가지 주요 단점이 있습니다. 주요 문제는 엔터티 모델이 NHibernate 또는 이와 유사한 방식으로 유지되면 View가 모델 속성을 업데이트하자마자 NHibernate 이러한 변경 사항을 데이터베이스에 유지할 수 있다는 것 입니다. 저장 / 취소 버튼이있는 편집 화면에서는 제대로 작동하지 않습니다. 실제로는 모든 것을 일괄 적으로 대기하고 유지하도록 선택할 수 있지만 모델을 변경하면 변경 사항을 커밋한다는 아이디어가 있습니다.

따라서 읽기 전용 화면에서 모델 속성에 직접 바인딩하여 벗어날 수는 있지만 불일치가 발생합니다.

또한 대부분의 모델은 구현 INotifyPropertyChanged되지 않으므로 초기 표시 후 화면 상태가 변경되면 적합한 바인딩 대상이 아닐 수 있습니다.

자동 속성이 쉬우므로 항상 View를 Model이 아닌 ViewModel에 바인딩하는 것이 좋습니다. 일관되고 단순하며 향후 변경을 지원할 수있는 최고의 유연성을 제공합니다.


나는 당신의 대답을 좋아합니다. 편집 / 저장 화면을 언급하면 ​​+1입니다. 그러나 속성을 두 번 (모델에서 한 번, 다시 뷰 모델에서) 쓰는 것은 어려울 것입니다. 또한 개발 시간이 늘어날 것입니다. 그렇게하는 것이 정당하다고 생각합니까?
Pravin Patil

9
@Pravin Patil-fwiw, 내가 바로 가기를 할 때마다 나중에 돌아가서 고쳐야 할 때 저를 저주했습니다. ViewModel에서 속성을 다시 구현하려는 노력은 비교적 적습니다. 특히 읽기 전용 인 경우 (개인 구현 자와 함께 자동 구현 된 속성을 사용할 수 있기 때문). 사실 대부분의 경우 모델은 ViewModel과 다른 데이터 구조입니다. 보기에 영향을주지 않고 모델을 유연하게 변경할 수 있습니다. 보기를 변경해야할수록보기가 테스트하기 어렵 기 때문에 더 좋습니다.
Scott Whitlock

4
@Scott Whitlock : 2 년 동안 NHibernate를 사용하여 WPF 응용 프로그램을 개발해 왔으며 모델에 직접 바인딩하는 데 아무런 문제가 없었습니다. 실제로 모델 속성이 변경되면 바인딩하려는 내용에 관계없이 변경 내용과 거의 동일합니다. 그리고 나중에 ViewModel 자체에서 라우팅을 수행해야 할 때 필요한 시간을 투자 할 가치가 없었습니다. 나는 YAGNI (아직) 접근법을 따르고 어려움이 없습니다. 나는 당신과 다른 사람들 이이 문제에 대해 약간 독단적이라고 생각합니다.
팔콘

16

요점 ViewModel은의 모델이라는 것 View입니다.

속성이 아닌 ViewModel을에 바인딩해야합니다 (직접적으로는 아님).ViewModel


8

두 가지 방법 모두 허용됩니다.

ViewModel에만 바인딩하는 것은 "MVVM- 순수한"접근 방식이며 레이어 간 분리를 향상시킵니다. 모델에 바인딩하는 것이 일반적으로 더 빠르고 편리합니다.

레이어 (프로젝트 크기, 향후 유지 보수 문제, 작업중인 모델 유형 등)를 완전히 분리해야 할 충분한 이유가없는 한 모델에 바인딩합니다.


7

당신이보고있는 것은 bind through라는 개념입니다. 즉, 모델에 name이라는 속성이 있고 뷰 모델이 추가 편집이나 변환 없이이 속성을 노출하면 모델에 바인딩 할 수 있습니다.

의사 코드 :

 {Binding: MyViewModel.MyModel.Name}

이것은 뷰 모델에서 'Fluff'속성의 양을 줄이기 위해 수행되지만 불행히도 장기적으로 나쁜 생각입니다. 뷰 모델의 개념은 뷰가 모델에 종속되지 않도록하는 것입니다. 바인딩을 통해 모델에 name이라는 속성이 포함되어 있는지 확인해야합니다. 그렇지 않으면 구현이 중단됩니다.

그러나 뷰 모델까지만 바인딩하는 경우 모델을 변경할 수 있으며 뷰 모델에서 Name이라는 이름의 속성 만 볼 수 있으므로 뷰는 알 수 없습니다.

이제 모델이 인터페이스를 기반으로하는 경우 특정 상황에서이를 완화 할 수 있습니다. 따라서 인터페이스에 ModuleName 속성을 노출 한 IBaseDetails가있는 경우 다음을 수행 할 수 있습니다.

의사 코드 :

 {Binding: MyViewModel.MyModel.ModuleName}

당신이 만드는 어떤 모델이 IBaseDetails 인터페이스를 만족시키는 한, 당신의 황금은 이것이 가장 중요한 경우라는 것을 명심하십시오. 일반적으로 당신은 뷰 모델을 커버하는 모델 주위에 항상 90 %가 더 좋습니다.


2

Model-> ViewModel에서 많은 마찰이 발생하면 AutoMapper와 같은 것을 시도하십시오. 복사 속성과 관련된 tedium을 수동으로 제거합니다.


1

나는 같은 의심을 품고 여기에 왔으며 항상 모델 대신 모델을보기 위해 바인딩 할 것이라고 확신했습니다.

Angular Reactive Form을 사용하십시오. 뷰 모델의 일부 정보를 사용하여 양식 그룹을 작성하지만 나중에 양식에 액세스해야합니다. 값을 가져오고 복사하는 값은 자동 매퍼 또는 수동을 사용하여 모델에 값을 표시합니다.보기 모델의 속성에 입찰하는 것보다 더 아름다운 것은 없다고 생각합니다. 예를 들어 프로젝트 이름이있는 프로젝트 뷰 페이지가 있다고 가정 해 보겠습니다. 클라이언트 이름 등

프로젝트에는 클라이언트가 있기 때문에 프로젝트와 클라이언트 사이에는 관계가 있습니다. 따라서이 수준에서 관계에 대해 신경 쓰지 않아야합니다.보기에 프로젝트 이름과 클라이언트 이름을 시각적으로 표시해야하므로 뷰 모델 프로젝트 이름과 클라이언트 이름에 2 개의 속성을 배치하여 뷰 컨트롤을 나중에 모델의 모든 구조에서 가져온 코드의 속성에 값을 제공하는 것에 대해 걱정할 것입니다.

저장 / 취소의 경우 모델을 업데이트해도 더 이상 깨끗한 것은 없습니다.


이 게시물은 읽기 어렵습니다 (텍스트의 벽). 더 나은 형태로 편집 하시겠습니까 ?
gnat

당신은 간다, 건배.
Ivan Carmenates García
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.