Предисловие: предыдущая статья вводит инкапсуляцию добавления KO, удаления, модификации и поиска, что действительно спасает много кода JS. Блогер - человек, который любит быть ленивым. Он всегда чувствует, что эти основные дополнения, делеции, модификации и проверки могут напрямую генерировать эффекты страниц с помощью инструмента, и код не требуется. Это было бы так круто. Итак, я изучал грамматику T4. Хотя я не полностью справился с этим, у меня было общее понимание. Итак, сегодняшняя статья: быстро генерируйте страницы через шаблоны T4.
Статьи серии nockoutjs:
Bootstraptable и NockoutJs объединяются для достижения функции добавления, удаления, модификации и проверки [1]
Bootstraptable и NockoutJs объединяются для достижения функции добавления, удаления, модификации и проверки [2]
Bootstraptable + nockoutjs объединяется, чтобы реализовать решение добавления, удаления, модификации и проверки (3) Два вида могут завершить добавление, удаление, изменение и проверку
1. Введение в использование T4
Мы знаем, что при добавлении просмотров в MVC эффект добавления, удаления, удаления, модификации и проверки страницы может быть автоматически сгенерировано. Это связано с тем, что MVC имеет встроенные базовые шаблоны для добавления, удаления, модификации и проверки. Синтаксис этих шаблонов заключается в использовании T4, так где же эти шаблоны? После поиска связанных статей я обнаружил, что расположение шаблонов версий MVC4 и ниже очень отличается от расположения MVC5 и выше.
• Расположение шаблона для MVC4 и следующих версий: VS Установка каталога +/itemtemplates/csharp/web/mvc 2/codementaltes. Например, файлы блогера D:/Program (x86)/Microsoft Visual Studio 12.0/Common7/IDE/ITEMTEMPLATES/CSHARP/WEB/MVC 4/CODETARTATES.
Найдите шаблон, соответствующий CSHTML, и есть соответствующие файлы TT, которые добавляют, удаляют, изменяют и проверяют
• Место шаблона MVC5 и выше: непосредственно дайте шаблон местоположение блогера D:/программы (x86)/Microsoft Visual Studio 12.0/common7/ide/extensions/microsoft/web/mvc/spaffolding/templates
Как только вы узнаете об этом, следующим шагом является реконструкция шаблона и добавить свой собственный сгенерированный контент. Вы можете непосредственно скопировать шаблоны списка и редактировать в самопрокатирование, но, подумав об этом, лучше не касаться встроенного MVC. Не лучше создавать свои собственные шаблоны самостоятельно.
Создайте новую папку под корневым каталогом текущего веб -проекта, назовите его кодирующими, а затем скопируйте две папки шаблонов MVCcontrollerEmpty и MVCView в шаблоне MVC в папку CodeTemplates, удалите исходные шаблоны внутри него, а затем создайте несколько новых шаблонов, как показано на рисунке ниже:
Таким образом, когда мы добавляем новый контроллер и создаем новый представление, мы можем увидеть наш индивидуальный шаблон:
2. Введение кода T4
Приведенное выше представляет, как создать свой собственный шаблон. После того, как шаблон будет построен, вы должны начать вносить в него соответствующий контент. Если грамматика T4 расширена, эта статья будет бесконечной. Заинтересованные садовники могут искать в саду. Есть еще довольно много статей. Давайте посмотрим на несколько шаблонов здесь. Еще одна вещь, которую следует отметить, заключается в том, что после MVC5 суффикс файлов T4 -шаблона был изменен на T4, а предыдущие шаблоны всегда заканчивались TT. Не смотря на различия в их синтаксисе, подсчитано, что не должно быть никакой разницы.
1. Controller.cs.t4
Зачем переписать этот пустой шаблон контроллера? Блогер считает, что многие методы добавления, удаления, модификации и проверки должны быть написаны вручную, и это много проблем с написанием шаблона напрямую. Давайте посмотрим на код реализации в шаблоне:
<#@ template language="C#" HostSpecific="True" #><#@ output extension="cs" #><#@ parameter type="System.String" name="ControllerName" #><#@ parameter type="System.String" name="ControllerRootName" #><#@ parameter type="System.String" name="Namespace" #><#@ parameter type="System.String" name = "areaname"#> <#var index = controlerName.lastIndexof ("controller"); var modelname = controlername.substring (0, index);#> с использованием системы; с помощью system.collections.generic; с использованием system.linq; с использованием system.web; с использованием system.web.mvc; с использованием testko.models; namespace <###=###=#=#######################. #>: 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.ally.ally); JsonResult add (<#= modelname#> odata) {<#= modelname#> model.add (odata); return json (new {}, jsonrequestbehavior.alloghet);} // Обновление объекта [httppost] public jsonResult update (<#= modelname#> odata) #> Model.update (odata); return json (new {}, jsonrequestbehavior.allyget);} // delete entity [httppost] public jsonresult delete (list << #= modelname #> odata) {< #= modelname #> model.delete (odata); Jsonrequestbehavior.allowget);}}}Этот контент не сложно понять. Просто проверьте сгенерированный код контроллера:
Использование System; с использованием system.collections.generic; с использованием system.linq; с использованием system.web; с использованием system.web.mvc; с использованием testko.models; имен -пространство testko.controllers {public class usercontroller: controller {public actionResult () {return view (); {wublicResult edit (пользовательская модель) {return View) {return Probode) {return Publice) {return Pelief) JsonResult get (int limit, int offset) {return json (new {}, jsonrequestbehavior.allowget);} // добавить Entity [httppost] public jsonResult add (user odata) {usermodel.add (odata); return json (new {}, jsonrequestbehavior.allowget);} // Обновление объекта [httppost] public jsonresult update (user odata) {usermodel.update (odata); return json (new {}, jsonrequestbehavior.allowget);} // удалить Entity [httppost] public jsonResult delete (list <user> odata) {usermodel.delete (odata); return json (new {}, jsonrequestbehavior.allayget);}}}2. koindex.cs.t4
Этот шаблон в основном используется для создания страниц списков, с общим кодом следующим образом:
<#@ template language = "c#" hostspecific = "true"#> <#@ output extension = ". if (islayoutpageselected) {#>@{viewbag.title = "<#= viewname#>"; <#if (! String.isnullorempty (LayoutPagefile)) {#> Layout = "<#= layoutPageFile#>"; <#}#>} <#} else {#>@@@klayout = eull = eull = eull; html> <html> <head> <meta name = "viewport" content = "width = device-width"/> <title> < #= viewName #> </title> <link href = "~/content/bootstrap/css/bountstrap.min.css" rel = "stylessheet"/> <link href = "~/content/bootstrap-table/bootstrap-table.min.css" rel = "stylesheet"/> <script src = "~/scripts/jquery-1.9.1.min.js"> </script> <script src = "~/content/bootstrap/js/bootstrap.min. src = "~/content/bootstrap-table/bootstrap-table.min.js"> </script> <script src = "~/content/bootstrap-table/locale/bootstrap-table-Zh-cn.js"> </script> <script src = "~/scripts/nockout/nockout-3.4.0.0.min src="~/scripts/knockout/extensions/knockout.mapping-latest.js"></script><script src="~/scripts/extensions/knockout.index.js"></script><script src="~/scripts/extensions/knockout.index.js"></script><script><script src = "~/scripts/extensions/nockout.index.js"> </script> <script src = "~/scripts/extensions/nockout.bootstraptable.js"> </script> <script type = "text/javascript"> $ (function () {var viewmodel = {biddid: "div_index"> $ (induction: {var eviewModel = {div_index "> $ () "/<#= ViewDatatyPeshortName#>/get", pageSize: 2,}, urls: {del: "/<#= viewDatatyPeshortName#>/delete", edit: "/<#= viewDatatyPeshortName#>/edit", add: "/<#= ViewDatatyPashortNam : {}}; ko.bindingViewModel (viewModel);}); </script> </head> <body> <#pushindent ("");}#> <div id = "body bare"> <futne data-bind = "click: addclick" type = кнопка "> <pran aria-hidden =" true "> </span> </span> </span> </span> </span> </span> </span> </span> </span> </span> </span> </span> </span> </span> </span> </span> </span> </span> </span>. data-bind = «Нажмите: editClick" type = "button"> <span aria-hidden = "true"> </span> modify </button> <button Data-bind = "Щелкните: deleteclick" type = "button"> <span aria-hidden = "true"> </span> delete </button> </div> <tail-bind = "boopstraptable: bootstraptable" thrate> </button> </div> <tale-bind = "thraptable data-checkbox = "true"> </th> <#ienumerable <propertyMetadata> Properties = modelMetAdata.Properties; foreach (свойство PropertyMetAdata в свойствах) {if (Property.Scaffold &&! Property.isprimaryKey &&! GetValueExpression (свойство)#> </th> <#}}#> </tr> </thead> </table> <#// Следующий код закрывает тег, используемый в случае представления с использованием страницы макета, а теги и HTML и HTML -теги в случае обычного просмотра#> <#if (! {ClearIndent ();#> </body> </html> <#}#> <#@ include file = "modelmetAdatafunctions.cs.include.t4"#>Добавить индекс представления и выберите этот шаблон
Полученное содержание страницы
@{Layout = null;} <! Doctype html> <html> <head> <meta name = "viewport" content = "width = device-width"/> <tite> index </title> <link href = "~/content/bootstrap/css/bootstrap.min.css" rolf = " href = "~/content/bootstrap-table/bootstrap-table.min.css" rel = "stylesheet"/> <script src = "~/scripts/jquery-1.9.1.min.js"> </script> <script src = "~/content/bootstrap/js/bootstrap.min. src = "~/content/bootstrap-table/bootstrap-table.min.js"> </script> <script src = "~/content/bootstrap-table/locale/bootstrap-table-Zh-cn.js"> </script> <script src = "~/scripts/nockout/nockout-3.4.0.0.min src = "~/scripts/nockout/nockout-3.4.0.min.js"> </script> <script src = "~/scripts/nockout/extensions/nockout.mapping-latest.js"> </script> <script src = "~/scripts/extensions/nockout.index.js"> <cript> <cript> <cript> src = "~/scripts/extensions/nockout.bootstraptable.js"> </script> <script type = "text/javascript"> $ (function () {var viewmodel = {bindid: "div_index", tableparams: {url: "/user/get", paterize: 2,}, urls: {url: "/user/get", paterize: 2,}, urls: {url: "/user/get", 2,}, ur "/User/edit", добавить: "/user/edit",}, QueryCondition: {}}; ko.bindingViewModel (viewModel);}); </script> </head> <body> <div id = " aria-hidden="true"></span>Add</button><button 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 data-bind = "bootstraptable: bootstraptable"> <tr> <th data-checkbox = "true"> </th> <th data-field = "name"> name </th> <th Data-field = "fullName"> FullName </th> <th Data-field = "Age"> Age </th> <th Data-sield = "des"> </th> <th> data-field = "createTime"> createTime </th> <th Data-field = "strCreatetime"> strCreatetime </th> </tr> </thead> </table> </body> </html> index.cshtmlМы перенесли просмотр, упомянутую в предыдущей статье на страницу, чтобы нам не приходилось каждый раз передавать ее из контроллера. Слегка измените имя столбца таблицы, и страница может работать.
Вот несколько моментов, которые нужно оптимизировать:
(1) Условия запроса не были получены. Если вы изучите синтаксис T4 немного глубже, вы можете добавить характеристики в поля, которые необходимо запросить, чтобы определить, какие поля необходимо запросить, а затем автоматически генерировать соответствующие условия запроса.
(2) Имена столбцов таблицы, по -видимому, генерируются через свойства поля атрибута. Это похоже на первое пункт, и оба должны изучать грамматику T4.
3. Koedit.cs.t4
Третья страница шаблона - это отредактированный шаблон, а его грубый код заключается в следующем:
<#@ template language = "c#" hostspecific = "true"#> <#@ output extension = ". Флажок, который использует div в Bootstrapstring booltype = "system.boolean"; версия обязательно mvcversion = новая версия ("5.1.0.0"); Bool iscontrolhtmlattributessupported = mvcversion> = требуется mvcversion; // Следующая цепочка, используя код, представлена на странице, целеустремлена, целесообразно, кодекс для участия в файле и маркировку для участия, целесообразно, целесообразно, целесообразно, ноучия, целесообразное, целесообразное просмотр. View.if (ispartialView) {#> <#} else if (islayoutpageselected) {#>@{viewbag.title = "<#= viewname#>"; <#if (! String.isnullorempty (layoutpagefile)) {#> layout = "<#= mayoutpagefile#>"; ViewName#> </h2> <#} else {#>@{layout = null;} <! Doctype html> <html> <Head> <meta name = "viewport" content = "width = device-width"/> <title> <#= viewname#> </title> </head> <body> <#pushInd ("); {#> <#if (! islayoutpageselected && isbundleconfigpresent) {#>@scripts.render ("~/bundles/jquery")@scripts.render ("~/bundles/jqueryval") <#}#> <#els src = "~/scripts/jQuery-<#= jQueryVersion#>. Min.js"> </script> <script src = "~/scripts/jquery.validate.min.js"> </script> <script src = "~/scripts/jquery.validate.UnObtrize.min.min.min.js> </jquery.validate.Unobtrize.min.min.min.min.min. id = "formedit">@html.hiddenfor (model => model.id) <div> <#ienumerable <propertymetadata> Properties = modelMetAdata.properties; Foreach (PropertyMetadata Property в свойствах) {if Property.scaffold && Property.isprimaryKey &&! {#> <div> @html.labelfor (model => model. <#= getValueExpression (свойство)#>, "<#= getValueExpression (свойство)#>", new {@class = "Control-label col-xs-2"}) <div> @html.textbox for (model => model. = "form-control", data_bind = "value:editModel.<#= GetValueExpression(property) #>" })</div></div><#}}#></div><div><button type="button" data-dismiss="modal"><span aria-hidden="true"></span>Close</button><button type="submit"><span aria-hidden = "true"> </span> save </button> </div> </form> <#var index = viewDatypeName.lastIndexof ("."); var modelName = viewDatypEname.substring (index+1, viewDatatypename.length-index-1); src = "~/scripts/extensions/nockout.edit.js"> </script> <script type = "text/javascript"> $ (function () {var model = @html.raw (newtonsoft.json.jsonconver.serializeObject (model : {отправить: model.id == 0? }); </script> <#if (islayoutpageselected && seriencecriptlibraries && isbundleconfigpresent) {#>@screess scripts {@scripts.render ("~/bundles/jqueryval")} <#}#> <#els src = "~/scripts/jQuery-< #= jQueryVersion #>. Min.js"> </script> <script src = "~/scripts/jquery.validate.min.js"> </script> <script src = "~/scripts/jquery.validate.UnoBtrize.min. src = "~/scripts/jquery.validate.unobtrusize.min.js"> </script> <#}#> <#// Следующий код закрывает тег, используемый в случае представления, используя страницу макета, а теги и HTML -теги в случае регулярного представления#> <#if (! {ClearIndent ();#> </body> </html> <#}#> <#@ include file = "modelmetAdatafunctions.cs.include.t4"#>Сгенерированный код:
@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"}) <div>@html. @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 {@class = "Control-label col-xs-2"}) <div> @html. "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.textfor (model => model.des, @slolol " @ @ @@slolol @ @@slolol @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @html.texfor (model. data_bind = "value: editmodel.des"}) </div> </div> <div> @html.labelfor (model => model.createtime, "createtime", new {@class = "Control-label col-xs-2"}) <div> @html.textfor (model => model.createme. data_bind = "value: editmodel.createtime"}) </div> </div> <div> @html.labelfor (model => model.strcreatetime, "strcreatetime", new {@class = "Control-label col-xs-2"}) <div> @html.textfor (model => model.crate @leamtetetetet. "Form-Control", data_bind = "value: editmodel.strcreateTime"}) </div> </div> <div> <button Type = "Кнопка" data-dismiss = "modal"> <span aria-hidden = "true"> </span> Close </button> <button = " aria-hidden="true"></span>Save</button></div></form><script src="~/Scripts/extensions/knockout.edit.js"></script><script type="text/javascript">$(function () {var model = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model));var ViewModel = {formid: "Formedit", EditModel: Model, URLS: {отправить: model.id == 0? '}}}}}}}; ko.bindingedItViewModel (viewModel);Конечно, код также должен быть немного изменен. Добавляя страницу пользовательского шаблона, пока установлена соответствующая модель объекта в фоновом режиме, вам нужно только создать два новых пользовательских представления на передней части, а простое дополнение, удаление, модификация и поиск могут быть завершены без написания предложения кода JS.
3. Привязка избранного компонента
Выше приведено синтаксис добавления, удаления, модификации и поиска T4 упаковки T4. Все компоненты страницы - это в основном текстовые поля. Однако в реальных проектах многие страницы запроса и редактирования будут иметь раскрывающиеся ящики для отображения. Как мы должны иметь дело с раскрывающейся коробкой? Если вы не держите это в секрете, просто дайте решение. Например, мы можем разместить источник данных раскрывающегося ящика в фоновом режиме на странице редактирования.
Объект пользователя
[DataContract] Пользователь открытого класса {[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 Strcreatetime {get; набор; } [Datamember] public String Department {get; набор; } [DataMember] Отдел публичных объектов {get; набор; }}Затем отредактируйте страницу
public actionResult edit (пользовательская модель) {model.departments = departmodel.getData (); return view (model);}Затем свяжите переднюю часть.
<div> <label for = "txt_des"> Департамент </label> <select id = "sel_dept" data-bind = "options: editmodel.departments, optionstext:" name ', optionsvalue:' id ', value: editmodel.departmentid "> </selet> </div>
Код JS не должен быть изменен. При добавлении или редактировании поля департамента могут быть автоматически добавлены в ViewModel.
Конечно, раскрывающиеся коробки, используемые многими из наших проектов, не просто выберите, потому что простой стиль Select действительно уродливый, так много компонентов избранных производится, например, Select2, MultiSelect и т. Д. При использовании этих компонентов для инициализации выбора вы обнаружите, что раскрывающийся путь в интерфейсе больше не является простым тегом Select, но состоит из многих других тегов, настроенных компонентом. Давайте возьмем компонент SELECT2 в качестве примера, чтобы увидеть, возможно ли инициализировать напрямую в соответствии с вышеизложенным.
Мы добавляем последнее предложение, чтобы редактировать код JS, инициализированный страницей:
<script type = "text/javascript"> $ (function () {var model = @html.raw (newtonsoft.json.jsonconvert.serializeobject (model)); var viewmodel = {formid: "formedit", editmodel: model, urls: {upper: model == 0? " "/User/update"}, валидатор: {fields: {name: {validators: {notempty: {сообщение: 'Имя не может быть пустым!Благодаря дополнениям и изменениям это действительно возможно! Анализ причины, хотя страница HTML изменяется после инициализации компонента SELECT2, компонент в конечном итоге представит выбранное значение для исходного элемента управления SELECT. Я не знаю, будут ли другие компоненты инициализации избранных, кроме этого, кроме Select2, и они ждут проверки. Тем не менее, здесь есть одна вещь, которую нужно объяснить. Перед инициализацией Select2 параметры в раскрывающемся поле должны быть связаны с значением, то есть инициализация компонента должна быть размещена после ko.applybinding ().
4. Резюме
На этом этапе KO в сочетании с начальной обработкой шаблонов и использование избранных элементов управления в основном доступно, и, конечно, его все еще нужно улучшить. Если у вас есть время спустя, блоггер разберет комбинацию других передних компонентов и KO, таких как наш самый распространенный контроль даты. Если у вас есть какие -либо вопросы, пожалуйста, оставьте мне сообщение, и редактор ответит всем вовремя. Большое спасибо за вашу поддержку сайту wulin.com!