10

私は、データビュー付きのASP.NET MVCビューモデルに類似した、妥当性検査ビューにバインドできる検証ルールを含むJavaScriptビューモデルオブジェクトを使用したいと考えています。次に、サーバに投稿する前にそのオブジェクトの生存期間の特定の段階でそのオブジェクトのValidateメソッドを呼び出すようにします。ViewModelベースの妥当性検査(角度付き)

これは、UIが非常に軽くスマートではなく、ビューで表されるどのビューモデルでも、変更を必要とするMVVMのようなアプローチに近づくことを可能にします検証ルールを変更するためにビューマークアップに追加します。

このようにして、MVCのデータアノテーションを利用して、サーバー上でルールを使用してシリアライズ可能なビューモデルを構築し、そのモデルとすべての検証などをJSONとしてクライアントに返すこともできます。

どのようにして、このタイプの検証を、Angularで行うことができますか?もっと一般的な、要素/モデルごとのプロパティの検証はディレクティブによって実現されますか?

+0

私はこのほぼ正確な設定でプロジェクトを始めているので、これに対する答えを聞いて欲しいです! –

+0

あなたのモデルには何を使用していますか? PetaPoco、エンティティのフレームワークなど私は過去のオブジェクトクラスにモデルの基本オブジェクトクラスを拡張する部分的なクラスを作成することによって検証を追加しました。私はクラスのvalidateメソッドを呼び出すことができ、それはerrosを返します(私はWPFアプリケーションでこのアプローチを使用しました)が、私はangluarアプリケーションにこれをシリアル化する方法がわかりません。ビューモデルが消費し、必要なオブジェクトを解析する別のサービスである必要があります。 –

+0

私は古いPOCOを使用していますが、バリデーションルールのモデルプロパティにデータ注釈属性を使用しています。 MVCは既にViewPageにModelMetadataを追加するので、このようなサービスを提供しています。このページでは、ng-initを使ってこれをモデルに渡すことができますが、それはかなり不器用です。 – ProfK

答えて

7

私が取り組んでいる最新のプロジェクトであなたを助けるかもしれない何かを実装しました。フロントエンドではAngularJSを使用し、バックエンドではASP.NET WEB APIを使用します。すべてのHTMLフォームは、POCOクラスに含まれるプロパティとデータ注釈に基づいて自動的に生成されます。

サーバー側にはエンティティとDTOがあります。私のエンティティはデータベース固有の注釈を含み、DTOにはビュー固有の注釈が含まれています。 1つのクラスに1つのプロパティを表示し、UIをどのようにレンダリングするかの簡単な例を示します。ここでは、サーバー側のオブジェクトは、次のとおりです。

public class Discount 
{ 
    [StringLength(40)] 
    [Required] 
    public String Name { get; set; } 
} 

public class DiscountDto : IDto<Discount> 
{ 
    [Display(ResourceType = typeof(ApplicationStrings), Name = "Name", ShortName = "Name_Placeholder")] 
    [UI(Row = 1, Width = 6)] 
    public String Name { get; set; } 
} 

このプロパティはそのようなUIにレンダリングされる:

<div class="form-group"> 
    <label class="col-sm-2 control-label"> Name: </label> 
    <div class="col-sm-6"> 
    <input class="form-control" ng-model="model[options.key]" required="required" maxlength="40" placeholder="Enter the name..."> 
    </div> 
</div> 

<input />フィールドはrequiredplaceholdermaxlengthプロパティの自動設定があります。 HTMLラベル、ブートストラップカラムの幅は、カスタムのUIデータアノテーションに基づいて自動的に設定されます。 Row = 1はこのフィールドをフォームの最初に表示することを意味し、Width = 6はフィールドが6:class="col-sm-6"の列幅を占める必要があることを意味します。ラベルテキストとプレースホルダテキストは、リソースファイルから取得されます。 これはあなたがして

:-)上読んで探しているものであれば、私は、パラメータとしてDTOの名前を取り込み、コントローラMetaController作成しています。たとえばapi/Meta/DiscountDTOを。このコントローラは、DTOオブジェクトと関連エンティティのすべてのプロパティをループし、データ注釈を取り出してFormMetadataクラスに変換し、List<FormMetadata>をクライアントに返します。 FormMetadataクラスは、アノテートをフロントエンド開発者にとってより読みやすいものにするために、IsRequired,IsDisplayedIsReadonlyなどのプロパティを含んでいます。ここでMetaControllerからの抜粋です:

var type = Type.GetType("<DTO_goes_here>"); 
List<FormMetadata> formMetadata = new List<FormMetadata>(); 

foreach (var prop in type.GetProperties()) 
{ 
    var metadata = new FormMetadata(); 
    metadata.Key = prop.Name.ToLower().Substring(0, 1) + prop.Name.Substring(1, prop.Name.Length - 1); 
    metadata.Type = prop.PropertyType.FullName; 

    object[] attrs = prop.GetCustomAttributes(true); 

    foreach (Attribute attr in attrs) 
    { 
     if (attr is RequiredAttribute) 
     { 
      metadata.IsRequired = true; 
     } 
     else if (attr is StringLengthAttribute) 
     { 
      var sla = (attr as StringLengthAttribute); 
      metadata.MinLength = sla.MinimumLength; 
      metadata.MaxLength = sla.MaximumLength; 
     } 
     // etc. 
    } 

    formMetadata.Add(metadata); 
} 

Nameプロパティのために、次のJSONを返します。このエンドポイント:私が取るカスタム角度指令<entity-form />を作成したクライアント側で

{ 
    "$id":"3", 
    "key":"name", 
    "display":"Name", 
    "type":"System.String", 
    "placeholder":"Enter the name...", 
    "isRequired":true, 
    "isEditable":true, 
    "isDisplayed":true, 
    "isReadonly":false, 
    "displayInList":true, 
    "width":6, 
    "row":1, 
    "col":0, 
    "order":0, 
    "maxLength":40, 
    "minLength":0, 
    "lookup":null, 
    "displayAs":null 
} 

DTOの名前を次のようにパラメータとして指定します。

<entity-form entity-type="DiscountDTO"></entity-form>この指示文はMetaControllerを呼び出してDiscountエンティティの検証規則を取得し、返された規則に基づいてフォームを表示します。フォームをレンダリングするには、angular-formlyという素晴らしいライブラリを使用します。このライブラリは、HTMLを書くことなくjavascriptからフォームを作成することを可能にします。ここでは角形についてあまり詳しく説明しませんが、基本的にレンダリングしたいフォームの詳細を含むJavascriptオブジェクトを作成し、それを角度形式の指示に渡して、フォームのレンダリングを行います君は。

{ 
    "key": "text", 
    "type": "input", 
    "templateOptions": { 
    "label": "Text", 
    "placeholder": "Type here to see the other field become enabled..." 
    } 
} 

だから、私は基本的にMetaControllerから返されたメタデータを取得し、ビルドアップ:これはあなたがに渡すオブジェクトの種類の基本的な例であるアンギュラformly「テキスト」のラベルで<input />ボックスをレンダリングします角度的に形式的に理解してそれを角度形式の指示に渡し、私のためにその形を表現するオブジェクトです。私はこの答えがより多くの例などで長く長くなっている可能性があることを知っていますが、これは読まれることが多いと感じました。私はこれが十分な情報を与えることを願っています。

私はこれより一般的なオープンソースにそれを作るのが大好きだ - 誰もがこのような何か私がMVC and MVVM with AngularJSによる

+0

私はあなたがここでやったことが好きです。私が探しているものではありませんが、かなり啓発しています。 – ProfK

+0

非常にきちんとした - 正確に何を探していたのですか –

1

:-)知っているように取り組んで興味を持っている場合、AngularJSはMVVMデザインパターンに従っています。

あなたはAdding Unobtrusive Client Validation from the Microsoft .NET MVC Framework to Angularのようなものが必要だと思います。

カスタムHTMLヘルパーをRazor用に作成する場合は、Validation in Angular forms(2部構成)を参照してください。

ngvalが安定でないと思われると思われます。

+1

著者がコントローラをView Modelと呼び、基本的に '$ scope'をモデルと呼ぶ、あなたの最初のリンクに同意できません。いいえ、AngularはMVVMではなく、AngularコンテキストのModelがView Modelに相当し、他の(実際の)モデルがサーバー側ドメインモデルであるMVCであると強く反対します。 他のリンクは非常に面白くて便利なようですが、ありがたいです。 – ProfK

+0

@ ProffK MVVMについての私の理解はあなたのものと同じですが、私はあなたに同意しますが、リンクが役に立つと思っています:) –

関連する問題