2011-08-08 11 views
4

私はWPF(MVVM)の背景から来て、MVC 2に移行しようとしています。MVC2には、提出するために使用するコマンド/コマンドボタン<input>ビューをレンダリングしようとすると非表示にすることができます。ASP MVC 2 CanExecuteスタイルコマンドを実装するためのパターン

MVVMの世界では、コマンドがICommandインターフェイスを実装でき、非常に便利なCanExecuteメソッドがありました。 ASP MVC 2に似たものがあるのだろうか?

私が考えることができる唯一の方法は、ViewModel(CanSave)のフラグを確認し、その表示/非表示に応じて<input>タグを確認できるようにするためです。

基本的に私は2つのバージョンのウェブサイトを実行したい、1つは読み取り専用モードで、もう1つは編集モードです。

説明が必要な場合はお知らせください。

答えて

2

ASP .NET MVCには、従来のASP.NETとWPFに見られるように、「コントロール」の概念はありません。 ASP.NET MVCの基本ブロックは、<input>,<button>などのHTML要素です。もちろん、これはあなたが探している機能(ICommandインタフェースの実装)を提供していません。

あなたが見ているシナリオ(フォームの2つのモード)は、ビューレベルで扱われる(おそらくになるはずです)。あなたはすでに正しい方向に向かっています:あなたのモデルに「CanSave」プロパティを持ち、Viewでこれを使って生成されたものを判断します。

例:

<% if (Model.CanSave) 
    { %> 
     <p>First Name: <%= Html.TextBox("firstname", Model.firstname) %> </p> 
<% } 
    else 
    { %> 
     <p>First Name: <%=Model.firstname %></p> 
<% } %> 

おそらく、このシナリオのために非常に便利な... DisplayTemplatesEditorTemplatesをチェックアウトすることをお勧めします。ブラッドウィルソンは良い仕事をするhere

それはあなたがこれに移動するのに役立ちます:あなたのビューがきれいで素敵になり

<%= (Model.CanSave) ? Html.EditorFor(x => x.firstname) : Html.DisplayFor(x => x.firstname) %> 

を...。

+0

tnx。それが私の頭の中で –

0

私が見つけた方法の1つは、アクションに入れることができるFilter属性を使用することですが、サーバー側でのみCanExecuteを処理します。 GUI側については

、ユーザーが特定のアクションを実行するためにPriviligedされた場合に文がチェックする場合に置くより良い方法を見つけるcouldntの(つまり編集/ボタンを削除します)

1

あなたはMVCはそれがだ、これを行うために得ることができない場合このVBスタイルの擬似コードのようなものを手作業で作る価値があるのです。これには...

コントロールのサブクラス化。

痛みはそれほどではありませんが、中程度のものです。したがって、中規模から大規模のアプリケーションにのみ適しています。しかし、彼らのためにそれの価値がある。

Interface BaseUIControl 
    Property Enabled as Boolean 
    Property Visible as Boolean 
    Property Name as String 
    Property EntireStateAsXML as string ' You can use this to do EVERYTHING!   

Interface UserActionItem 
    Event Clicked(sender as UserActionItem ... don't pass anything from UI namespaces!) 

Class MyButton (or link, etc.) Implement BaseUIControl, UserActionItem Inherits UI.Button 

これはどのように役立ちますか?基本的に欠けている機能を置き換えました。あなたのコントローラ(またはアプリケーション層)はUIコンポーネントをインターフェイスのみで認識できるため、UIタイプを表示する必要はありません。

もっと...

あなたはすべてを制御するには、この理念を活用することができます。これは私に数千時間の猿コードを保存しました。

Interface TextControl 
    Property Value as text 

Interface CheckControl 
    Property Checked as boolean 

上記の2つはかなり基本的です。あなたはMyCheckBoxとMyTextBoxをUIバージョンから継承し、適切なものを実装します。

もちろん、すべてのコントロールをループし、自動検証(ループスルーして各フォームのXMLを取得してフォーム全体の自動バインドを行う)という共通コードを設定することもできます。

Interface ValidationBase 
    Property Required as Boolean 

テキストまたは数値のみのマスクや2つのサブクラスに組み込まれrestricitonsを持っている場合は...

Interface ValidationNumeric   
    Property MinVal, MaxVal as double 

Interface ValidationText 
    Property MinLen, MaxLen as double 

はありません、それはあなたのためのデータベースに行くことはありません。しかし、これは敷物の下に一杯の荒れ果てた掃除をする。

UIデザイナーでこれらのプロパティ値を設定することもできます。はい、BLをUIでベッドに入れますが、BLのUIが1つしかない場合は、実際にうまく機能します。

今画像UIにどのような作品リストボックス/複数選択、ダブルリストピッカーコントロール、チェックするリストボックス、オプションボタン/チェックボックスのグループボックスのようなものが混在するUI ...

Interface Selector 
    property Items as list (of string) 
    property SelectedItems as list (of string) 

使用あなたのジェネリックルーチンは、彼らがどのように見えるかを気にすることはできません!サブクラス化されたUI部分は、適切な値を設定/取得するために実装されます。コントロールは、他の項目から単純な値に設定することを許可また

...我々は(そうでなければ、単独で残す、SetValueEquationにtrueの場合、設定された値)SetValueTriggerEquation、ActivatesEquation(ungray /グレー)、「validationEquation」を追加し、 (基本的には、反射を使用しているかのようにバインドされたオブジェクトから値を取得します)Expression Evaluator(ネットタイプを読む)

また、メインフォームをサブクラス化し、すべてのサブコントロールから再帰的にXMLの画面全体を表示し、そのようにシリアル化します。独自のクラスに非UIレイヤーでこれらを実装させ、それを使用してUI状態を完全に(de /)シリアライズし、それらを使用してUIを読み込むことができます(ビジネスオブジェクトに関連する場合)。

それは信じられないほどどのくらい複雑なアプリケーションを簡素化する。私たちは、250K LOCで250種類の用紙を記入する1200+データ入力パネル(...ページ...私たちは厚いクライアントアプリケーションです)を持っています。フォーム定義には各コントロールの「名前」が含まれており、これは画面から生成されたXMLから取得されます。多くの画面にコードがないか、または単純なコードしかないので、おそらく500K LOCを保存しました。すべてのデータバインディング、検証などは、インタフェースを参照する共通ルーチンによって処理されます。

私が言うように、これは大きなアプリでのみ機能します。ただし、機能の90%を開発するのに少なくとも2〜3週間かかります。それを成熟させる2年の開発者の間でおそらく別の月。あなたがICommandとその利便性を気にしているなら、私はあなたのアプリが大きいと思います。私は15-20の適度に複雑なページで投資回収を行います。

1

質問を正しく理解していれば、これをカプセル化するためにControllerCommandクラスを書くことができます。このような何か:

public class DetailsModel 
{ 
    public guid Id { get; set;} 
    // some other viewmodel properties 
    public ControllerCommand Edit { get; set; } 
} 

をあなたがHtmlHelperに拡張メソッドを書くことができます内蔵のものを置き換えるために:

public class ControllerCommand 
{ 
    public string Action { get; set; } 
    public string Controller { get; set; } 
    public object RouteValues { get; set; } 
    public bool IsEnabled { get; set; } 
} 

あなたの詳細は、このようにそれを使用する場合がありますViewModelに

public MvcHtmlString CommandLink(this HtmlHelper html, string linkText, ControllerCommand command, object htmlAttributes) 
{ 
    if (command.IsEnabled) 
    { 
     return html.ActionLink(linkText, command.Action, command.Controller, command.RouteValues, htmlAttributes); 
    } 
    else 
    { 
     return MvcHtmlString.Create(linkText); 
     // perhaps return <span class="disabled-command">linkText</span> 
    } 
} 
関連する問題