2014年10月29日 星期三

[iThome 第七屆鐵人賽 26] View相關的處理 - Model的Metadata介紹

Service層的部份到目前為止已經介紹了基本的CRUD,搜索方面的自動處理和一些資料驗證的部份。是時候來切換一下看在View的部份框架還能夠幫到什麽。

在這一篇將會介紹所謂的Model Metadata,並且概念上來說如何用框架打造一些好用的功能,並且在下一篇來實作。

Model Metadata概述

首先來看一下所謂的Model Metadata。當我們傳一個ViewModel到View的時候,Mvc其實有做一些處理,透過Reflection的方式產出這個ViewModel的Model Metadata。

有了這些Model Metadata,在View才能夠使用一些Html的Helper來產生一些html。例如,Html.ValidationMessageFor就會依照Model Metadata的ModelStateDictionary來顯示欄位的錯誤訊息。

另外一個例子就是,像我們在ViewModel欄位會定義DisplayAttribute讓使用Html.DisplayFor的時候,顯示的名稱不是Property欄位名稱,而是 DisplayAttribute設定的內容。

Html Helper能夠得到這些內容,其實都是從Model Metadata取得資料。因此,換個角度想,如果我們能夠在Model State裡面塞一些資訊,在View裡面就可以變得更加簡單,因此我們就來看一下框架要做到的效果是什麽。

Model Metadata是如何產生?

Model Metadata基本上就是一個ViewModel欄位相關資訊,而如何告訴這些資訊是透過DataAnnoationation的Attribute來做到。

image

 

ModelMetadata如何產生

上面這張圖的上半段是介紹一般我們定義ViewModel的DataAnnotation之後,在View的呈現,Mvc的HtmlHelper就會幫我們產生出DataAnnotation所做的設定內容。

下面則是基本Mvc在背後幫我們做的事情。首先,在Mvc有一個ModelMetadataProvider(準確一點描述應該是一個DataAnnotationsModelMetadataProvider),會依照DataAnnotation產生出ModelMetadata。

有了這個ModelMetadata,HtmlHelper和EditorTemplates,就可以用這些資訊,顯示出這些內容。

知道ModelMetadata有和意義?

到目前為止我們對於ModelMetadata有些概念之後,下一個問題就是,這個對於我們有什麼幫助?

我們先來思考一個問題,假設今天我有一個欄位代表著Email,請問我需要做什麼Mvc才會產生出html 5 的 email input?

答案是我們需要對哪一個property增加一個EmailAttribute

可是換一個角度想,如果一個欄位代表是email,這個欄位通常名稱一定會是xxxEmail,甚至可能就叫做Email。我們能不能夠就依照這個欄位名字決定讓Mvc產生出html 5的email Input?而不需要自己額外用一個EmailAttribute說這是一個Email。

或者說假設今天我需要產生出來的表單是以TextArea顯示而不是用input的text顯示,以目前Mvc來說我們需要把Property加上DataTypeAttribute設定為“MultilineText”就可以。

假設我們整個團隊的Property命名規則就是,如果要用TextArea,Property 名稱一定要有TextArea,例如ContentTextArea,那不能夠依照Property名稱來決定這個欄位是TextArea嗎?

上面舉得兩個例子,其實都是在提到一個內容,那就是,UI顯示的內容可以進一步依照我們團隊自己的Convention(習慣),例如NamingConvention(命名習慣)去產生出正確的UI 內容,而不需要而外多加設定。

如何做到

概念上面如下圖:

image
ExtensibleModelMetadataProvider示意圖

橘色的部分是框架的建設造的。基本上,我們會有一個自訂的ModelMetadataProvider。這個ExtensibleModelMetadataProvider會由DI注入一些Process的實作,這些實作才是實際上對ModelMetadata的處理。

有了這些Process的處理之後,ModelMetadata就會被改變。這個時候View顯示的時候就會依照這些ModelMetadata做呈現。

結語

這一篇介紹了ModelMetadata的概念。有了ModelMetadata作為產生UI的一些額外資訊,在框架可以用Convention的方式來修改ModelMetadata達到產生對應的UI呈現。

在下一篇將會進入實際的實作。


沒有留言 :

張貼留言