8:View的Model和Tag Helpers

♣ 视频地址:https://www.bilibili.com/video/av38392956/?p=7html

 

VIEWMODEL,首先讲下概念:数据库

  咱们一般有数据库的Model,一般叫Entity Model(使用EF和EF Core都知道),数据库里的字段在Model里都有一个类,里面的属性是一一对应的,好比FirstName,LastName,BirthDate服务器

  可是咱们Controller想返回一个视图,视图所须要的信息并非上面三个字段的原始信息,它须要完成的名字Name,须要一个年龄Age而不是出生日期,因此咱们给这个View返回的Model最好是Name和Age,那咱们就新建一个Model就叫View Model,也能够叫DTO(Data Transfer Object)数据转换的对象框架

  而咱们再Controller里所作的就是把左边的Model转化为右边的Model,而后传递给Viewide

咱们新给Student类加了一个属性BirthDate,以下图函数

而且在服务里面把这个属性加上,以下图spa

而后咱们创建ViewModels的文件夹,而且添加一个类再添加三个属性,这个类是给HomeController里Index用的,以下图3d

接下来咱们回到Controller,把vms传给View当参数指针

public IActionResult Index()
        {
            var list = _repository.GetAll();
            //Select =>将序列的每一个元素投影到新表单中,在这里就是HomeIndexViewModel
            var vms = list.Select(x => new HomeIndexViewModel
            {
                Name = $"{x.FirstName}{x.LastName}",
                //当前时间减去x.BirthDate,得出来的天数除以365
                Age = DateTime.Now.Subtract(x.BirthDate).Days / 365
            });

            return View(vms);
        }
View Code

 而后回到视图,修改下代码后运行,看到效果出来了以下图code


接下来咱们进一步改进下代码

如今咱们传进来是个集合,类型是HomeIndexViewModel,可是这样并不特别正确,最好的方法是这样,咱们建一个StudentViewModel把HomeIndexViewModel的属性给它,以下图

而后HomeIndexViewModel里改成下面这样

接着咱们回到HomeController,改一下咱们的代码

 public IActionResult Index()
        {
            var list = _repository.GetAll();
            //Select =>将序列的每一个元素投影到新表单中,StudentViewModel
            var vms = list.Select(x => new StudentViewModel
            {
                Id = x.Id,
                Name = $"{x.FirstName}{x.LastName}",
                //当前时间减去x.BirthDate,得出来的天数除以365
                Age = DateTime.Now.Subtract(x.BirthDate).Days / 365
            });
            var vm = new HomeIndexViewModel
            {
                Students = vms
            };
            return View(vm);
        }
View Code

 而后回到视图里,把上面的集合改成一个类,下面这接用Model.Students便可,运行看到也能够,以下图

 


 

下面作第二个需求,咱们把名字当作超连接,而后点击名字,转到学生的属性信息页面...

首先咱们先写Action,传入一个id,根据id来找咱们的学生

   public IActionResult Detail(int id)
        {
            var student = _repository.GetById(id);
            return View(student);
        }

接着,咱们去建接口,接口的返回类型为T,以下图

而后咱们去实现这个接口,这里我把学生信息提到构造函数里了

public class InMemoryRepository : IRepository<Student>
    {
        private readonly List<Student> _students;
        public InMemoryRepository()
        {
            _students =  new List<Student>
            {
                new Student
                {
                    Id = 1,
                    FirstName = "Nick",
                    LastName = "Carter",
                    BirthDate =new DateTime(1980,1,4)
                },
                new Student
                {
                    Id = 2,
                    FirstName = "Kevin",
                    LastName = "Richardson",
                    BirthDate =new DateTime(1974,6,16)
                },
                new Student
                {
                    Id = 3,
                    FirstName = "Howie",
                    LastName = "D",
                    BirthDate =new DateTime(1978,12,5)
                }
            };
        }
        public IEnumerable<Student> GetAll()
        {
            return _students;
        }

        public Student GetById(int id)
        {
            Student st = _students.FirstOrDefault(s => s.Id == id);
            return st;
        }
    }
View Code

 如今咱们创建Detail视图,以下图

咱们先使用路由试一下,结果好用,以下图

咱们用queryString,查询字符串的方式试一下,结果也好用,以下图

那若是路由里面有id,后面又加上querystring,它显示那个呢?显示路由对应的,以下图

 如今有3个学生,那咱们在路由里输入5呢,固然是报空指针异常的错啦,由于Model为Null,因此Null.FirstName就会发生空指针异常,以下图

 这时候咱们应该判断Model是否为Null,能够在View里判断,但最好的方式是在Controller里判断

      public IActionResult Detail(int id)
        {
            var student = _repository.GetById(id);
            if (student == null)
            {
                //若是student为null,怎定向到HomeController下的Index方法
                return RedirectToAction("Index");
            }
            return View(student);
        }
View Code

而且在Index视图里加上超连接,以下图

 这时候再试试若是在路由里输入id为5,能够看到从新定向到Index页面了

那上面的超连接呢是比较低级的写法,既然咱们用了MVC框架,那么MVC里面确定有些东西来帮助咱们创建超连接

 下图就是MVC里的写法,第一个参数是超连接的名字,第二个参数是action的名字,第三个是参数id,若是这样写,那么它就会找视图对应的Controller里的Action

 

若是你想让它跳转到其余的Controller对应的Action,只须要在后面再加一个Controller的参数便可,以下图


上面看到了两个写法,那么还有一个是ASP.NET Core出现以后的叫Tag Helpers(上面叫作Html Helpers...),咱们接下来使用Tag Helpers来操做

使用Tag Helpers以前须要进行引用,首先须要在Views文件夹下面添加_ViewImports.cshtml,以下图

 我们先无论这个文件具体是作什么的,这个View不渲染任何东西,它在这里就至关于提供了一些指令,告诉Razor引擎这些视图应该怎么被渲染,而且这些View应该有哪些功能,有点引用的意思

咱们在里面写上下面这一段,意思就是我想把Microsoft.AspNetCore.MVC.TagHelpers这个Assembly里面全部的TagHelper在咱们全部的视图里能够使用的话,加上*,就这么写就能够了

接下来咱们回到index视图页面,以下图asp-开头的就是ASP.NET Core 里面超连接的Helper,虽然它看起来像Html元素的属性,其实不是

MVC框架Razor引擎,它在服务端看到这个东西的时候(在这里就是超连接),它就会对它进行处理,渲染,在服务器端给它处理掉,而后返回客户就是Html

 

而后咱们在明细页加一个返回,也用Tag Helper,以下图

相关文章
相关标签/搜索