序文:前の記事では、KOの追加、削除、変更、検索のカプセル化を紹介します。これは、実際に多くのJSコードを節約します。ブロガーは怠け者になるのが好きな人です。彼は常に、これらの基本的な追加、削除、変更、チェックがツールを介してページ効果を直接生成できると感じており、コードは必要ありません。それはとてもクールでしょう。それで、私はT4の文法を研究しました。私はそれを完全に習得していませんでしたが、私は一般的な理解を持っていました。したがって、今日の記事:T4テンプレートを介してページをすばやく生成します。
knockoutjsシリーズ記事:
BootstraptableとKnockoutjsが組み合わさって、追加、削除、変更、およびチェックの機能を実現します[1]
BootstraptableとKnockoutjsが組み合わさって、追加、削除、変更、およびチェックの機能を実現します[2]
Bootstraptable + knockoutjsは組み合わせて、追加、削除、変更、およびチェックの解決策を実現します(3)2つのビューモデルは、追加を完了し、削除、変更、およびチェックすることができます
1。T4の使用の紹介
MVCにビューを追加すると、追加、削除、変更、チェックのページ効果が自動的に生成できることがわかっています。これは、MVCには、追加、削除、変更、およびチェックするための基本的なテンプレートが組み込まれているためです。これらのテンプレートの構文はT4を使用することです。これらのテンプレートはどこにありますか?関連する記事を検索した後、MVC4以下のバージョンテンプレートの位置はMVC5以下の場所とは大きく異なることがわかりました。
•MVC4のテンプレートの場所と次のバージョン:vsインストールディレクトリ +/itemTemplates/csharp/web/mvc 2/codetemplates。たとえば、ブロガーのd:/プログラムファイル(x86)/microsoftビジュアルスタジオ12.0/common7/ide/itemtemplates/csharp/web/mvc 4/codetemplates。
CSHTMLに対応するテンプレートを見つけ、追加、削除、変更、およびチェックする対応するTTファイルがあります
•MVC5以降のテンプレート場所:ブロガーのテンプレートの場所を直接指定しますd:/プログラムファイル(x86)/microsoftビジュアルスタジオ12.0/common7/ide/extensions/microsoft/web/mvc/scaffolding/templates
これがわかったら、次のステップはテンプレートを改造し、独自の生成コンテンツを追加することです。リストを直接コピーしてテンプレートを自己変容に編集できますが、考えた後は、内蔵MVCに触れない方が良いです。独自のテンプレートを自分で作成する方が良いことではありません。
現在のWebプロジェクトのルートディレクトリの下に新しいフォルダーを作成し、IT CodetEmplatesに名前を付けてから、MVCテンプレートの2つのテンプレートフォルダーMVCCONTROLLEREMPTYとMVCVIEWをコードテンプレートフォルダーにコピーし、元のテンプレートを削除してから、いくつかの新しいテンプレートを作成します。
このようにして、新しいコントローラーを追加して新しいビューを作成すると、カスタマイズされたテンプレートを確認できます。
2。T4コード紹介
上記では、独自のテンプレートを作成する方法を紹介します。テンプレートが構築されたら、対応するコンテンツの詰め物を開始する必要があります。 T4の文法が拡張されている場合、その記事は無限になります。興味のある庭師は庭で検索できます。まだたくさんの記事があります。ここでいくつかのテンプレートの内容を見てみましょう。もう1つ注意すべきことは、MVC5の後、T4のテンプレートファイルの接尾辞がT4に変更され、以前のテンプレートが常にTTで終了したように見えることです。構文の違いを見ることなく、違いはほとんどないと推定されています。
1。Controller.CS.T4
なぜこの空のコントローラーテンプレートを書き直すのですか?ブロガーは、追加、削除、変更、チェックの多くの方法を手動で書く必要があると考えており、テンプレートを直接記述するのは大きな問題であると考えています。テンプレートの実装コードを見てみましょう。
<#@ Template Language = "C#" HOSTSPIFIFIFIFIFIFIFIFIFIFIC = "true"#> <#@ output endix = "cs"#> <#@ parameter type = "system.string" name = "controlonname"#> <#@ parameter type = "system.string" name = "controllorrootname" name = "areaname"#> <#var index = controllname.lastindexof( "controller"); var modelname.substring(0、index);#> system.collections.generic; system.linqを使用; system.web;を使用してsystem.web.web;を使用して、system.web.mvc; #>:controller {public ActionResult index(){return view();} public ActionResult edit(<#= modelname#> model){return view(model);} [httpget] public jsonresult get(int limit、int offset){return json(new {}、jsonrequestbehavior.Allowget);追加(<#= modelname#> odata){<#= modelname#> model.add(odata); return json(new {}、jsonrequestbehavior.allowget);} // update entity [httppost] public jsonresult update(<#= modelname #> odata) {}、jsonrequestbehavior.allowget);} // delete entity [httppost] public jsonresult delete(list <<#= modelname#> odata){<#= modelname#> model.delete(odata); return json(new {}}、jsonrequestbehavior.};このコンテンツを理解するのは難しくありません。生成されたコントローラーコードを確認するだけです。
System; System.Collections.Generic; System.linq;を使用してSystem.web;を使用してSystem.web.mvc;を使用して使用しています。Testko.models; namespace testko.controllers {public class usercontroller:controller {public result index(){return view();} public rurult edit(view()} {model view(Model)} jsonresult get(int lime、int offset){return json(new {}、jsonrequestbehavior.allowget);} // add entity [httppost] public jsonresult add(user odata){usermodel.add(odata); return json(new {}、jsonrequestbehavior.allowget);} // update entity [httppost] public jsonresult update(user odata){usermodel.update(odata); return json(new {}、jsonrequestbehavior.allowget);} // delete entity [httppost] public jsonresult delete(list <user> odata){usermodel.delete(odata); return json(new {}、jsonrequestbehavior.allowget);}}}2。KOINDEX.CS.T4
このテンプレートは、主にリストページを生成するために使用され、一般コードは次のとおりです。
<#@ Template Language = "C#" HOSTSPIFIFIFIFIFIFIFIFIFIFIFIFIFIFIFIFIFIC = "true"#> <#@ output extension = "。cshtml"#> <#@ include file = "imports.include.t4"#> <#//ステートメントの場合は、ファイルヘッダーコードとマークアップのファイルヘッダーコードとマークアップを出力します。 if(islayoutpageselected){#>@{viewbag.title = "<#= viewname#>"; <#if(!string.isnullorempty(layoutpagefile)){#> layout = "<#= layoutpagefile#>"; <#}} html> <html> <head> <meta name = "Viewport" content = "width = device-width"/> <title> <#= viewname#> </title> <link href = "〜/content/bootstrap/css/bootstrap.min.css" rel = "stylesheet"/> <link href = "〜/content/bootstrap-table/bootstrap-table.min.css" rel = "styleSheet"/> <script src = "〜/scripts/jquery-1.9.1.min.js"> </script> <scrits src = "〜/content/boottrap/js src = "〜/content/bootstrap-table/bootstrap-table.min.js"> </script> <script src = "〜/bootstrap-table/bootstrap-table-zh-cn.js"> </script> <script src = "〜/script/knkkout/knokkout-3.4.0.0.0.0.0.0.0.0.min.j src = "〜/scripts/knockout/extensions/knockout.mapping-latest.js"> </script> <script src = "〜/scripts/extensions/knockout.index.js"> </script> <src = "〜/scripts/extensions/knockout.index.js src = "〜/scripts/extensions/knockout.index.js"> </script> <scrip = "〜/scripts/extensions/knockout.bootstraptable.js"> </script> <script> "text/javascript"> $(function(){var viewmodel = {bindid: "divindid:" "divindid:" "/<#= viewdatatypeshortname#>/get"、pagesize:2、}、urls:{del: "/<#= viewdatatypeshortname#>/delete"、編集: "/<#= viewdatatypeshortname#>/edit"、add: "/<#= viewdatepshortname#> :{}}; ko.bindingviewmodel(viewmodel);}); </script> </head> <body> <#pushIndent( "");}#> <div = "Toolbar"> <ボタンデータバインド= "クリック:クリック"タイプ= "ボタンを追加します" type = "button"> <span aria-hidden = "true"> </span> modify </button> <button data-bind = "click:deleteclick" type = "button"> <span aria-hidden = "true"> </span> </div> <table data-bind = "" boottraptable "> <tr <th data-checkbox = "true"> </th> <#iEnumerable <propertymetadata> Properties = modelmetadata.properties; foreach(propertymetadataプロパティのプロパティ){if(property.scaffold &&!property.isprimarykey &&!property.isforeignKey){#> < getValueExpression(プロパティ)#> </th> <#}}#> </tr> </thead> </table> <#//次のコードは、レイアウトページを使用してビューの場合に使用されるタグとボディとHTMLタグを閉じます。 {clearIndent();#> </body> </html> <#}#> <#@ include file = "modelmetadatafunctions.cs.include.t4"#>ビューインデックスを追加し、このテンプレートを選択します
取得したページコンテンツ
@{layout = null;} <!doctype html> <html> <head> <meta name = "viewport" content = "width =" device-width "/> <title> index </link> <link href ="〜/content/bootstrap/css/boottrap.min.css href = "〜/content/bootstrap-table/bootstrap-table.min.css" rel = "styleSheet"/> <script src = "〜/scripts/jquery-1.9.1.min.js"> </script> <scrits src = "〜/content/boottrap/js src = "〜/content/bootstrap-table/bootstrap-table.min.js"> </script> <script src = "〜/bootstrap-table/bootstrap-table-zh-cn.js"> </script> <script src = "〜/script/knkkout/knokkout-3.4.0.0.0.0.0.0.0.0.min.j src = "〜/scripts/knockout/knockout-3.4.0.min.js"> </script> <script src = "〜/scripts/nockout/extensions/knockout.mapping-latest.js"> </scrip src = "〜/scripts/extensions/knockout.bootstraptable.js"> </script> <script type = "text/javascript"> $(funcemodel = {bindid: "div_index"、tableparams:{url: "/user/get"、pagesize:2、urls: "/user/edit"、add: "/user/edit"、}、querycondition:{}}; ko.bindingviewmodel(viewmodel);}); </script> </head> <body> <div div = "Toolbar"> <ボタンデータバインド= " data-bind = "click:editclick" type = "button"> <span aria-hidden = "true"> </span> modify </button> <button data-bind = "click:deleteclick" type = "button"> <span aria-hidden = "true"> </span> delete </button> </div> <table bintable data-checkbox = "true"> </th> <th data-field = "name"> name </th> <th data-field = "fullname"> fullname </th> <th data-field = "age"> age </th data-field = "des"> des </th> <th data-field = "createtime"> createTime </th <th data-field = "strecreatetime"> streatetime </th> </tr> </thead> </table> </body> </html> index.cshtml前の記事に記載されているViewModelをページに移動したので、毎回コントローラーから渡す必要はありません。テーブルの列名をわずかに変更すると、ページが実行されます。
最適化されるいくつかのポイントを次に示します。
(1)クエリ条件は生成されていません。 T4の構文をもう少し深く調べると、どのフィールドをクエリする必要があるかを識別して、対応するクエリ条件を自動的に生成する必要があるフィールドに特性を追加できます。
(2)テーブルの列名は、属性のフィールドプロパティを介して生成されているようです。これは最初のポイントに似ており、両方ともT4の文法を研究する必要があります。
3。KOEDIT.CS.T4
3番目のテンプレートページは編集されたテンプレートであり、その大まかなコードは次のとおりです。
<#@ Template Language = "C#" HOSTSPIFIC = "true"#> <#@ output endix = "。cshtml"#> <#@ include file = "imports.include.t4"#>@ model <#= viewdatatypename#> <#// "form-control" bootstrapstring booltype = "system.boolean"; version rebymingmvcversion = newバージョンでdivを使用するチェックボックス。または通常のview.if.if(ispartialView){#> <#} else if(islayoutpageselected){#>@{viewbag.title = "<#= viewname#>"; < viewname#> </h2> <#} else {#>@{layout = null;} < {#> <#if(!islayoutpageselected && isbundleconfigpresent){#>@scripts.render( "〜/bundles/jquery")@scripts.render( "〜/bundles/jqueryval")<#}#> < jQueryversion#>。min.js "> </script> <script src ="〜/scripts/jquery.validate.min.js "> </scrip> <script src ="〜/jquery.validate.unobtrusive.min.js "> </script>} Model.id)<div> <#ienumerable <propertymetadata> Properties = modelmetadata.properties; foreach(Propertymetadataプロパティのプロパティ){if(property.scaffold &! property.isprimarykey &&!property.isforeignkey){#> <div> = getValue(#> < "<#= getValueExpression(Property)#>"、new {@class = "control-label col-xs-2"})<div> @html.textboxfor(model => model。<#= getValueExpression(プロパティ)#>、new {@class = "form-control"、data_bind = " })</div> </div> <#}}#> </div> <div> <button type = "button" data-dismiss = "modal"> <span aria-hidden = "true"> </span> close </button> <button = "submit"> <span aria-hidden = "true"> </span> viewdatatypename.lastindexof( "。"); var modelname = viewdatatypename.substring(index+1、viewdatatypename.length-index-1);#> <scripts/extens/knockout.edit.js "> </> <typs =" text/javascript "> $"> </javascript "> @html.raw(newtonsoft.json.jsonconvert.serializeObject(model)); var viewmodel = {formid: "formedit"、editModel:{submit:model.id == 0? {validators:{notempty:{message: 'naw nail oble veyt!'}}}}}; {@scripts.render( "〜/bundles/jqueryval")} <#}#> <#else if(islayoutpageselected && referenceScriptLibraries){#> <script src =/scripts/jquery- <#= jqueryversion#> src = "〜/scripts/jquery.validate.min.js"> </scrip> <scrip src = "〜/jquery.validate.unobtrusive.min.js"> </scrip> <scrip = "〜/scripts/jquery.validate.unobtrusive.min.min.js"> <レイアウトページを使用してビューの場合に使用され、通常のビューの場合のボディとHTMLタグ#> <#if(!ispartialView &&!islayoutpageselected){clearIndent();#> </body> </html> <#}#>@ <生成コード:
@model testko.models.user <form id = "formedit">@html.hiddenfor(model => model.id)<div> <div>@html.labelfor(model => model.name、 "name"、new {@class = "control-label col-xs-2"}) @class = "form-control"、data_bind = "value:editmodel.name"})</div> </div> <div> @html.labelfor(model => model.fullname、 "fullname"、new {@class = "control-label col-xs-2"}) @class = "form-control"、data_bind = "value:editmodel.fullname"})</div> </div> <div> @html.labelfor(model => model.age、 "age"、new {@closs = "control-label col-xs-2"})< "form-control"、data_bind = "value:editmodel.age"})</div> </div> <div> @html.labelfor(model => model.des、 "des"、new {@class = "control-label col-xs-2"})<div> @html.textboxfor( @model.des " data_bind = "value:editmodel.des"})</div> </div> <div> @html.labelfor(model => model.createtime、new {@class = "control-label col-xs-2"})<div> @html.textboxfor(model => createtime " @createtime" data_bind = "value:editmodel.createtime"})</div> </div> <div> @html.labelfor(model => model.streatetime、 "strreatetime"、new {@class = "control-label col-xs-2"})<div> @html.textboxfor(モデル=> model( @new) "form-control"、data_bind = "value:editmodel.streatetime"})</div> </div> <div> <button type = "button" button "data-dismiss =" span aria-hidden = "true"> </span> close </button> <button type = "shoct"> <span src = "〜/scripts/extensions/knockout.edit.js"> </script> <script type = "text/javascript"> $(function(){var model = @html.raw(newtonsoft.json.jsonconvert.SerializeObject(Model)); var viewmodel = {formid: "" "formid" "" "" Model.id == "/add": "/user/updation"} {name:{notempty: 'message:' nail oble veyt}}};もちろん、コードもわずかに変更する必要があります。カスタムテンプレートページを追加することにより、バックグラウンドの対応するエンティティモデルが構築されている限り、フロントエンドに2つの新しいカスタムビューを作成するだけで、JSコードの文を書くことなく簡単な追加、削除、変更、検索を完了できます。
3。選択コンポーネントの結合
上記は、T4パッケージの追加、削除、変更、および検索の構文を導入します。ページのすべてのコンポーネントは、基本的にテキストボックスです。ただし、実際のプロジェクトでは、多くのクエリと編集ページに表示されるボックスが表示されます。ドロップダウンボックスをどのように処理すればよいですか?秘密にしない場合は、解決策を与えてください。たとえば、編集ページの背景にドロップダウンボックスのデータソースを配置できます。
ユーザーのエンティティ
[dataContract] public classユーザー{[datamember] public int id {get;セット; } [datamember] public string name {get;セット; } [datamember] public string fullname {get;セット; } [datamember] public int age {get;セット; } [datamember] public string des {get;セット; } [DataMember] Public DateTime CreateTime {get;セット; } [datamember] public string streatetime {get;セット; } [datamember] public string departmentid {get;セット; } [datamember]公開部門{get;セット; }}次に、ページを編集します
public ActionResult edit(user model){model.departments = departmentModel.getData(); return View(model);}次に、フロントエンドをバインドします。
<div> <label for = "txt_des"> department </label> <select id = "sel_dept" data-bind = "options:editmodel.departments、optionstext: 'name'、optionsvalue: 'id'、value:editmodel.departmentid"> </select> </div>
JSコードを変更する必要はありません。追加または編集するとき、部門フィールドをViewModelに自動的に追加できます。
もちろん、私たちのプロジェクトの多くが使用するドロップダウンボックスは、単純な選択ではなく、単純な選択スタイルが非常にugいなので、Bloggerが以前に共有したSelect2、Multiselectなど、多くの選択コンポーネントが生成されています。これらのコンポーネントを使用して選択を初期化すると、インターフェイス上のドロップダウンボックスが単純な選択タグではなく、コンポーネントによってカスタマイズされた他の多くのタグで構成されていることがわかります。 select2コンポーネントを例として、上記に従って直接初期化することが実行可能かどうかを確認しましょう。
最後の文を追加して、ページで初期化されたJSコードを編集します。
<script type = "text/javascript"> $(function(){var model = @html.raw(newtonsoft.json.jsonconvert.serializeObject(model)); var viewmodel = {formid: "formedit"、editmodel:model、urls:{model.id = = = 0? "/user/update"}、validator:{fields:{vardators:{notempty: 'name nail empty}}}}}}}}}}}}}}}}}}};追加と編集を通して、これは確かに実行可能です!理由の分析、Page HTMLはSelect2コンポーネントを初期化した後に変更されますが、コンポーネントは最終的に元のSelectコントロールに選択された値を表示します。 Select2を除いて、他の選択の初期化コンポーネントがこのようになるかどうかはわかりません。ただし、ここで説明することが1つあります。 select2を初期化する前に、ドロップダウンボックスのオプションは値にバインドする必要があります。つまり、コンポーネントの初期化はko.applybinding()の後に配置する必要があります。
4。概要
この時点で、KOとBootstraptableテンプレートの生成と選択されたコントロールの使用が基本的に利用可能であり、もちろん改善する必要があります。時間があれば、ブロガーは、最も一般的な日付制御など、他のフロントエンドコンポーネントとKOの組み合わせを整理します。ご質問がある場合は、メッセージを残してください。編集者は、すべての人に時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!