zoukankan      html  css  js  c++  java
  • ASP.NET Core MVC Razor小记

    _Layout模板

    常规的页面一般由头部导航、左侧菜单、中间主体内容主成,而其中唯一变动的基本就只有中间主体内容了,而Layout模板就是用来做这样一件事,编写好模板,需要变动的地方则使用@RenderBody()方法

    image-20211214211357520

    _ViewStart

    我们尝试在_Layout模板的footer标签中增加一点内容,运行程序,发现也会跟着改动,明明在Index文件中未作任何操作

    image-20211214211644003

    image-20211214211653969

    这是因为有_ViewStart的存在,发现里面默认有这样一行代码

    @{
        Layout = "_Layout";
    }
    

    如果在Index中头部未声明使用任何模板则会使用ViewStart定义的默认模板,默认一般是不定义,如果赋值为null或其它默认,则优先使用页面中定义的

    image-20211214212021169

    页面加载顺序

    _ViewStart.cshtml-->_Index.cshtml-->_Layout.cshtml
    
    1. 首先_ViewStart在所有View加载之前加载,设置了默认的模板页
    2. 接着由Controller指定的页面查找Index.cshtml加载,并读取该页面的Layout设置(在头部@{}中设置,如未设置则使用默认模板)
    3. 最后根据Index页面的Layout设置的模板页查找对应的模板页加载

    我们尝试将ViewStart的Layout设置为_Layout1,运行程序,可以看到报错了

    image-20211214212521057

    View的查找规则:先查找Controller对应的文件夹,若未找到,则到View/Shard和Pages/Shard文件夹查找,若最终还是未找到,则抛出异常

    TagHelper

    TagHelper与HtmlHelper对比

    以下是在视图中使用TagHelper和HtmlHelper对比

    @model HelloCore.Models.Book
    @{
        Layout = null;
    }
    @*HtmlHelper*@
    @Html.EditorFor(m=>m.Name)
    @Html.LabelFor(m=>m.Name)
    <br />
    @*TagHelper*@
    <label asp-for=Name></label>
    <input asp-for=Name />
    

    通过浏览器F12看看这俩到底有啥区别

    image-20211214220717549

    emm..目前看起来生成后的代码是没有多大区别,个人感觉主要区别还是在写法上,TagHelper相对HtmlHelper更为接近原生写法

    比如,现在给它们都加一个样式,看看二者的写法

    image-20211214221141728

    自定义TagHelper

    创建一个类,名称建议以TagHelper结尾,并继承自TagHelper

    重写ProcessAsync方法

    public class LabelTagHelper : TagHelper
        {
            public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
            {
                //校验label是否设置了show-type
                if (output.Attributes.TryGetAttribute("show-type",out TagHelperAttribute tagHelperAttribute))
                {
                    //校验设置的show-type是否为bookCode
                    if (tagHelperAttribute.Value.ToString().Equals("bookCode"))
                    {
                        //设置该标签的class为codeColor样式
                        output.Attributes.SetAttribute("class", "codeColor");
                        //获取标签的Contne内容
                        string content = output.Content.IsModified ? output.Content.GetContent() : (await output.GetChildContentAsync()).GetContent(); ;
                        //设置Content
                        output.Content.SetContent($"MVP{content}");
                    }
                }
            }
        }
    

    效果如下:

    image-20211214224434314

    之所以会“乱码”,应该是编码问题,转一下就OK了

    TagHelper注册

    在_ViewImports中添加一行

    @addTagHelper *,HelloCore
    

    表示添加该程序集下所有TagHelper

    TagHelper的作用范围

    目前上面这种方式只能作用于label标签,如果p标签也要用,可以在类上加上特性注解

    [HtmlTargetElement("p")]
    public class LabelTagHelper : TagHelper{
    
    }
    

    但这样一来,label标签上就不起作用了

    改造一下:

    [HtmlTargetElement("p", Attributes = "show-type", ParentTag = "div")]
        [HtmlTargetElement("label", Attributes = "show-type", ParentTag = "div")]
        public class LabelTagHelper : TagHelper{
        
        }
    

    如果HtmlTargetElement设置多个,则是or的关系,也就是只要满足一个就会生效,通过Attributes和ParentTag属性会极大的缩小要作用的对象范围,ParentTag表示父标签

    如果个别标签想要屏蔽TagHelper,则可以在标签尖括号后加上叹号

    <!label show-type="bookCode" asp-for=Name class=codeColor></!label>
    
    自定义标签

    在页面中添加一个标签

    <BookCode>1001</BookCode>
    

    新增一个BookCodeTagHelper

    public class BookCodeTagHelper : TagHelper
        {
            public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
            {
                output.Attributes.SetAttribute("class", "codeColor");
                string content = output.Content.IsModified ? output.Content.GetContent() : (await output.GetChildContentAsync()).GetContent(); ;
                output.Content.SetContent($"MVP{content}");
            }
        }
    

    看看最后生成出来的HTML

    image-20211215213737249

    注意:TagHelper会将大驼峰的命名方式转换成小写并以“-”分割

    比如BookCodeTagHelper--->book-code

    强大的VS还会根据我们所写的TagHelper给予提示和纠错

    1

    TagHelper与页面之间的数据传递

    假设现在我们编号的前缀不再固定为“MVP”,我们可以这么做

    修改TagHelper

    image-20211215214712548

    修改页面

    <book-code prefix="@Model.Prefix"></book-code>
    

    还可以直接在标签中的prefix属性上传入整个@Model,然后在TagHelper中取出前缀属性拼接上去,效果是一样的

    取消标签输出

    自定义标签代码

    [HtmlTargetElement("div", Attributes = "suppress-type")]
        public class SuppressTagHelper : TagHelper
        {
            public string SuppressType { get; set; }
            public override void Process(TagHelperContext context, TagHelperOutput output)
            {
                if (SuppressType.Equals("Suppress"))
                {
                    output.SuppressOutput();
                }
            }
        }
    

    index代码

    <div suppress-type="Suppress" >1002</div>
    

    运行程序,可以看到页面中并未显示这个div,F12查看也并没有这个标签

    image-20211215220240243

    TagBuilder

    TagBuilder可以辅助生成标签

    [HtmlTargetElement("div", Attributes = "simple-type")]
        public class SimpleTagHelper : TagHelper
        {
            public string SimpleType { get; set; }
            public override void Process(TagHelperContext context, TagHelperOutput output)
            {
                if (SimpleType.Equals("1"))
                {
                    output.Content.SetHtmlContent("<p>傲慢与偏见</p>");
                }
                else if (SimpleType.Equals("2")) {
                    var p = new TagBuilder("p");
                    p.InnerHtml.Append("傲慢与偏见");
                    p.AddCssClass("codeColor");
                    output.Content.SetHtmlContent(p);
                }
            }
        }
    
    <div simple-type="1"></div>
    <div simple-type="2"></div>
    

    image-20211215221608910

  • 相关阅读:
    Python面向对象(类的成员之属性)
    Python面向对象(类的成员之方法)
    Python面向对象(类的成员之字段)
    Python面向对象(多态)
    Python面向对象(继承)
    Python面向对象(构造方法)
    Python面向对象(self参数、封装)
    Python面向对象(定义类和创建对象)
    Pangolin库的使用
    Combinations
  • 原文地址:https://www.cnblogs.com/chonglu/p/15690603.html
Copyright © 2011-2022 走看看