2016-10-13 2 views
0

私は自分のシステム内のさまざまなモジュールの構成フォーム用のベースビューモデルを実装しました。動的に作成されたビュー:クライアント側の検証のために、プロパティのメタデータをネストされたビューに移入しますか?

その基地ロジックでは、私は(USER-)派生のviewmodelの反映性質を反復し、動的ConfigItemのリストを作成していますが、次のように私の物が見え簡体

オブジェクト:

public class ConfigItem 
{ 
    public string Key { get; set; } 
    public object Value { get; set; } 
    public Type PropertyType { get; set; } 
    public ConfigType ConfigType { get; set; } 
    public string PostId { get; set; } 
}; 

"value"プロパティは、単純型または複合型(文字列、ブール画像など)のオブジェクトにすることができます。

ネストされたビューでは、すべてのConfigItemをループでレンダリングしています(それぞれをツールチップなどの追加情報で飾るためです)。 投稿フォームのバインディングについては、入力フィールドのname属性を設定しているので、値は元のviewmodelプロパティに戻されます。 DataAnnotation属性の検証は、サーバー側で機能します。今問題に

:我々はすべてのASPを知っているよう

は控えめな検証属性のjQueryをレンダリングする巧妙な機能が付属しています。残念ながら、私は元のプロパティの代わりにConfigItemsをレンダリングするときに私のメタデータをすべて失っているので、ASPは私の属性について知らない。 "Required"または "StringLength"。どのようにしてプロパティのメタデータを「持ち歩く」方法を知っている人はいますか?

最高のものは、私のConfigItemの値がExpression型のような式ツリーである可能性があるため、元のプロパティに「ポインタ」を添えて渡すことができます。しかし、私はそれを技術的に解決する方法を理解できませんでした。誰かがこれに少しの光を当てることができれば(あるいは、他のヒントを持っているかもしれない)、私はそれを高く評価します。ありがとう!

アップデート:私は、私はモデル状態を評価少しカスタムのHTMLヘルパー、と私ConfigItemsをレンダリングしてい :

@model ConfigItem  
<div class="value"> 
@switch (Model.DataType) 
{ 
    case ConfigDataType.String: 
     { 
      var value = Model.Value == null ? "" : Model.Value; 
      @Html.EditorFor(m => value, "string", Model.PostId) 
      break; 
     } 
    case ConfigDataType.Bool: 
     { 
      @Html.EditorFor(m => Model.Value, "", Model.PostId) 
      break; 
     } 
    case ConfigDataType.Image: 
     { 
      @Html.ConfigImage(Model.Key, m => Model.Value, Url.Action(ApplicationController.ActionUploadImage), Model.PostId) 
      break; 
     } 
} 
@if (!string.IsNullOrEmpty(Model.ValidationMessage)) 
{ 
    <span class="@errorClass"> 
     @Html.Raw(Model.ValidationMessage) 
    </span> 
} 
</div> 
+1

どのようにConfigItemsをレンダリングしていますか? JQuery AJAX経由で、またはあなたのコードによってのみ? –

+0

私は質問をさらに明確にするために更新しました。 –

+0

あなたの部分的なビューでスクリプトを失った、そうですか? –

答えて

0

public static MvcHtmlString ConfigItem<TModel>(this HtmlHelper<TModel> htmlHelper, ConfigItem configItem, bool isEditMode = false) 
    { 
     if (isEditMode) 
     { 
      if (!htmlHelper.ViewData.ModelState.IsValidField(configItem.PostId)) 
      { 
       var itemState = htmlHelper.ViewData.ModelState[configItem.PostId]; 

       if (itemState.Errors.Count > 0) 
       { 
        configItem.ValidationMessage = string.Join("</br>", Array.ConvertAll(itemState.Errors.ToArray(), i => i.ErrorMessage)); 
       } 
      } 
      return htmlHelper.Partial(EditorConfigItemPartialPath, configItem); 
     } 
     else 
     { 
      return htmlHelper.Partial(DisplayConfigItemPartialPath, configItem); 
     } 
    } 

ConfigItem EditorTemplateはこのようなものありませんあなたのスクリプトを見逃した場合は、以下のコードを使用できます:

loaの共通機能部分ビューへの鼎スクリプト:

function loadScript(url, callback){ 

    var script = document.createElement("script") 
    script.type = "text/javascript"; 

    if (script.readyState){ //IE 
     script.onreadystatechange = function(){ 
      if (script.readyState == "loaded" || 
        script.readyState == "complete"){ 
       script.onreadystatechange = null; 
       callback(); 
      } 
     }; 
    } else { //Others 
     script.onload = function(){ 
      callback(); 
     }; 
    } 

    script.src = url; 
    document.getElementsByTagName("head")[0].appendChild(script); 
} 

、以下のようなあなたのswitch文の中にこの関数を呼び出す:

@switch (Model.DataType) 
{ 
    case ConfigDataType.String: 
     { 
      var value = Model.Value == null ? "" : Model.Value; 
      @Html.EditorFor(m => value, "string", Model.PostId) 
      loadScript("~/Content/js/register.js", function(){ 
      //initialization code 
      }); 
      break; 
     } 
    case ConfigDataType.Bool: 
     { 
      @Html.EditorFor(m => Model.Value, "", Model.PostId) 
      loadScript("~/Content/js/register.js", function(){ 
      //initialization code 
      }); 
      break; 
     } 
    case ConfigDataType.Image: 
     { 
      @Html.ConfigImage(Model.Key, m => Model.Value, Url.Action(ApplicationController.ActionUploadImage), Model.PostId) 
      loadScript("~/Content/js/register.js", function(){ 
      //initialization code 
      }); 
      break; 
     } 
} 

あなたの必要なJavaScript

~/Content/js/register.jsを置き換え、それはあなたを助けることを願っています。

ありがとうございました

+0

お返事ありがとうございました。それはスクリプトを読み込むための素晴らしいテクニックです。しかし、私はjsを混乱させたくない代わりに、適切なhtml属性を生成するmvc機能を使用します。私のviewmodelプロパティが[必須]属性を定義している場合、私のヘルパーは自動的にhtml属性aria-required = "true"を生成します。したがって、ヘルパーは正しいモデル/プロパティのコンテキストを必要とします。 ご協力いただきありがとうございます! –

+0

私はこれらの属性は既にそこにあると思う、あなただけがあなたの部分的な視点に '邪魔にならない' Jsを得ていない。私の検証(データ注釈の検証)に直面したこの問題は、部分的なビューでは機能しません。そして、私はこのコードで控えめなjsを呼び出し、私のためにうまく動作します。 –

+0

オクラホマ大歓迎です。 –

関連する問題