• 第67章 完整定义nopCommerce Jquery DataTable插件之初始化查询表单


    1 实体定义

    1 Specialty

    namespace JsonTable.Domain.Students

    {

        ///

        /// 【专业--类】

        ///

        /// 摘要:

        ///     通过该实体类及其属性成员,用于实现当前程序【Json】.【领域】.【学生集】.【专业】实体与“[JsonTable].[Specialty]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        ///

        ///

        public class Specialty

        {

            ///

            /// 【编号】

            ///

            /// 摘要:

            ///     获取/设置专业实体1个指定实例的整型编号值。

            ///

            ///

            public int Id { get; set; }

            ///

            /// 【名称】

            ///

            /// 摘要:

            ///     获取/设置1个指定专业的名称。

            ///

            ///

            public string Name { get; set; }

            ///

            /// 【学生集】

            ///

            /// 摘要:

            ///     获取/设置学生表中的所有学生实例。

            ///

            ///

            public virtual ICollection StudentICollection { get; set; }

        }

    }

    2 Grade

    namespace JsonTable.Domain.Students

    {

        ///

        /// 【年级--类】

        ///

        /// 摘要:

        ///     通过该实体类及其属性成员,用于实现当前程序【Json】.【领域】.【学生集】.【年级】实体与“[JsonTable].[Grade]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        ///

        ///

        public class Grade

        {

            ///

            /// 【编号】

            ///

            /// 摘要:

            ///     获取/设置年级实体1个指定实例的整型编号值。

            ///

            ///

            public int Id { get; set; }

            ///

            /// 【名称】

            ///

            /// 摘要:

            ///     获取/设置1个指定年级的名称。

            ///

            ///

            public string Name { get; set; }

            ///

            /// 【班级集】

            ///

            /// 摘要:

            ///     获取/设置班级表中的所有班级实例。

            ///

            ///

            public virtual ICollection CategoryICollection { get; set; }

            ///

            /// 【学生集】

            ///

            /// 摘要:

            ///     获取/设置学生表中的所有学生实例,因为已经设定取消Category与Student之间的级联删除映射定义,该属性实例可以被定义也可以被注释掉,这里被注释掉了

            ///

            ///

            //public virtual ICollection StudentICollection { get; set; }

        }

    }

    3 Category

    namespace JsonTable.Domain.Students

    {

        ///

        /// 【班级--类】

        ///

        /// 摘要:

        ///     通过该实体类及其属性成员,用于实现当前程序【Json】.【领域】.【学生集】.【班级】实体与“[JsonTable].[Category]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        ///

        ///

        public class Category

        {

            ///

            /// 【编号】

            ///

            /// 摘要:

            ///     获取/设置班级实体1个指定实例的整型编号值。

            ///

            ///

            public int Id { get; set; }

            ///

            /// 【年级编号】

            ///

            /// 摘要:

            ///     获取/设置年级实体1个指定实例的整型编号值,同时结合“GradeSingleton”属性约束规则把该属性映射为班级表中的同名副键。

            ///

            ///

            public int GradeId { get; set; }

            ///

            /// 【名称】

            ///

            /// 摘要:

            ///     获取/设置1个指定班级的名称。

            ///

            ///

            public string Name { get; set; }

            ///

            /// 【单个年级】

            ///

            /// 摘要:

            ///     获取/设置年级实体的1个指定实例。

            ///

            ///

            public virtual Grade GradeSingleton { get; set; }

            ///

            /// 【学生集】

            ///

            /// 摘要:

            ///     获取/设置学生表中的所有学生实例。

            ///

            ///

            public virtual ICollection StudentICollection { get; set; }

        }

    }

    4 Student

      ///

        /// 【学生--类】

        ///

        /// 摘要:

        ///     通过该实体类及其属性成员,用于实现当前程序【Json】.【领域】.【学生集】.【学生】实体与“[JsonTable].[Student]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

        ///

        ///

        public class Student

        {

            ///

            /// 【编号】

            ///

            /// 摘要:

            ///     获取/设置学生实体1个指定实例的整型编号值。

            ///

            ///

            public int Id { get; set; }

            ///

            /// 【专业编号】

            ///

            /// 摘要:

            ///     获取/设置专业实体1个指定实例的整型编号值,同时结合“SpecialtySingleton”属性约束规则把该属性映射为学生表中的同名副键。

            ///

            ///

            public int SpecialtyId { get; set; }

            ///

            /// 【年级编号】

            ///

            /// 摘要:

            ///     获取/设置年级实体1个指定实例的整型编号值,同时结合“GradeSingleton”属性约束规则把该属性映射为学生表中的同名副键。

            ///

            ///

            public int GradeId { get; set; }

            ///

            /// 【班级编号】

            ///

            /// 摘要:

            ///     获取/设置班级实体1个指定实例的整型编号值,同时结合“CategorySingleton”属性约束规则把该属性映射为学生表中的同名副键。

            ///

            ///

            public int CategoryId { get; set; }

            ///

            /// 【学号】

            ///

            /// 摘要:

            ///     获取/设置学生实体1个指定实例的学号。

            ///

            ///

            public string Code { get; set; }

            ///

            /// 【姓名】

            ///

            /// 摘要:

            ///     获取/设置1个指定学生的姓名。

            ///

            ///

            public string Name { get; set; }

            ///

            /// 【单个专业】

            ///

            /// 摘要:

            ///     获取/设置专业实体的1个指定实例。

            ///

            ///

            public virtual Specialty SpecialtySingleton { get; set; }

            ///

            /// 【单个年级】

            ///

            /// 摘要:

            ///     获取/设置年级实体的1个指定实例。

            ///

            ///

            public virtual Grade GradeSingleton { get; set; }

            ///

            /// 【单个班级】

            ///

            /// 摘要:

            ///     获取/设置班级实体的1个指定实例。

            ///

            ///

            public virtual Category CategorySingleton { get; set; }

        }

    2 重构EFCoreContext

    using JsonTable.Domain.Students;

    using Microsoft.EntityFrameworkCore;

    namespace JsonTable.Data

    {

        ///

        /// 【EFCore上下文】

        ///

        /// 摘要:

        ///     获取/设置学生实体的数据库设置实例,用于实现指定实体与数据库指定表的CURD操作。

        ///

        ///

        public class EFCoreContext : DbContext

        {

            #region 拷贝构造方法

            ///

            /// 【拷贝构造方法】

            ///

            /// 摘要:

            ///    基类构造通过该构造方法中的参数实例,连接到指定数据库(SQL Server)数据库软件中数据库。

            ///

            ///

            public EFCoreContext(DbContextOptions options) : base(options)

            {

                //如果(SQL Server)数据库软件中没有指定的数据库, 当通过Code First模式时,在第1次生成数据库时,则通过下1行语句结合数据库连接字符串,在(SQL Server)数据库软件中生成指定的数据库数据库、表、字段和约束规则。

                Database.EnsureCreated();

                /*

                如果(SQL Server)数据库软件中没有指定的数据库, 当通过Code First模式时,在第1次生成数据库时,则也通过下行执行迁移和更新命令行的结合数据库连接字符串,在(SQL Server)数据库软件中生成指定的数据库数据库、表、字段和约束规则。

                Add-Migration Initialize(Initialize:自动生成的迁移类名,这里特指:20220803125612_Initialize.cs):

                Update-Database Initialize(通过自动生成的迁移类中的定义,自动在指定的数据库软件中生成指定的数据库、表、字段和约束规则)

                 */

            }

            #endregion

            #region 属性

            ///

            /// 【专业】

            ///

            /// 摘要:

            ///     获取/设置学生实体的数据库设置实例,用于实现当前程序【Json】.【领域】.【学生集】.【专业】实体与“[JsonTable].[Specialty]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

            ///

            ///

            public DbSet SpecialtyDbSet { get; set; }

            ///

            /// 【年级】

            ///

            /// 摘要:

            ///     获取/设置学生实体的数据库设置实例,用于实现当前程序【Json】.【领域】.【学生集】.【年级】实体与“[JsonTable].[Grade]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

            ///

            ///

            public DbSet GradeDbSet { get; set; }

            ///

            /// 【班级】

            ///

            /// 摘要:

            ///     获取/设置学生实体的数据库设置实例,用于实现当前程序【Json】.【领域】.【学生集】.【班级】实体与“[JsonTable].[Category]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

            ///

            ///

            public DbSet CategoryDbSet { get; set; }

            ///

            /// 【学生】

            ///

            /// 摘要:

            ///     获取/设置学生实体的数据库设置实例,用于实现当前程序【Json】.【领域】.【学生集】.【学生】实体与“[JsonTable].[Student]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)。

            ///

            ///

            public DbSet StudentDbSet { get; set; }

            #endregion

            #region 方法--私有/保护--覆写

            /// name="builder">模型生成器实例,用于把当前程序中实体和属性所定义的约束规则,映射到数据库指定表及其字段上。

            ///

            /// 【模型生成执行...】

            ///

            /// 摘要:

            ///     该方法把当前程序中实体和属性所定义的约束规则,映射到数据库指定表及其字段上。

            ///

            ///

            protected override void OnModelCreating(ModelBuilder builder)

            {

                //专业表约束规则,映射定义。

                builder.Entity().ToTable(nameof(Specialty));

                builder.Entity().HasKey(specialty => specialty.Id);

                //年级表约束规则,映射定义。

                builder.Entity().ToTable(nameof(Grade));

                builder.Entity().HasKey(grade => grade.Id);

                //设定取消Category与Student之间的级联删除映射定义。

                builder.Entity().HasMany(grade => grade.CategoryICollection)

                    .WithOne(category => category.GradeSingleton)

                    .HasForeignKey(category => category.GradeId)

                    .OnDelete(DeleteBehavior.Restrict);

                //班级表约束规则,映射定义。

                builder.Entity().ToTable(nameof(Category));

                builder.Entity().HasKey(category => category.Id);

                //学生表约束规则,映射定义。

                builder.Entity().ToTable(nameof(Student));

                builder.Entity().HasKey(student => student.Id);

              

                base.OnModelCreating(builder);

            }

            #endregion

        }

    }

    3 定义基础模型与查询模纪录

    1 IPagingRequestModel

    namespace JsonTable.Models

    {

        ///

        /// 【分页请求模型--接口】

        ///

        /// 摘要:

        ///    明确的指定间接继承于该接口模型纪录实例分页操作的是通过Jquery DataTabes插件来实现的。

        ///

        ///

        public partial interface IPagingRequestModel

        {

            ///

            /// 【页数】

            ///

            /// 摘要:

            ///     获取query DataTable插件当前显示页面的页数值(Jquery DataTable插件默认开始页为:0;而该属性实例则把该默认开始页设置为:1,如果使用默认Jquery DataTable插件,则插件最后页会现“没有匹配结果”异常,即Jquery DataTable插件会多出1页)。

            ///

            ///

            int Page { get; }

            ///

            /// 【页面大小】

            ///

            /// 摘要:

            ///     获取Jquery DataTable插件每页最多的行数值:(弹出窗口默认值)7, (常规页面默认值)15,PageSize>=1。 

            ///

            ///

            int PageSize { get; }

        }

    }

    2 BaseSearchModel

    namespace JsonTable.Models.SearchModel

    {

        /*

        BaseNopModel

            在nopCommerce定义中当前纪录定义是需要继承BaseNopModel纪录的,BaseNopModel纪录的主要作用是,在页面和渲染(显示)时 ,

        当前指定模型纪录(例如这里的StudentSearchModel,StudentSearchModel间接继承BaseNopModel)不能通过默认的MVC模板绑定,把指定模型纪录实例中的数据渲染(显示)出来时,

        这时指定模型纪录(例如这里的StudentSearchModel,StudentSearchModel间接继承BaseNopModel)就需要通过重写BaseNopModel.BindModel虚方法,实现MVC模板对指定模型纪录中属性成员及其实例的绑定,

        从而在页面渲染(显示)时,能够在页面渲染(显示)出该指定模型纪录中属性成员及其实例的相关数据。

            但在nopCommerce中通过默认的MVC模板绑定,都能够实现对指定指定模型纪录的绑定,因此nopCommerce中也没有任何1个指定模型纪录对BaseNopModel.BindModel虚方法进行了重写,所以为了简化实现,

        本人删除了当前纪录定义对BaseNopModel的继承。

         */

        /*

        IPagingRequestModel

            通过Jquery DataTabes插件实现分页操作,实际上是Jquery DataTabes插件分页与实体实例分页的结合与集成,nopCommerce开发者为了区分开Jquery DataTabes插件分页与实体实例分页,指定当前纪录定义继承于IPagingRequestModel接口,

        以指定继承该纪录的指定模型纪录实例的分页操作是Jquery DataTabes插件分页;并对nopCommerce程序中通过IPagedList和PagedList所实现的实体实例分页操作作出明确的区分。

         */

        ///

        /// 【基本查询模型--纪录】

        ///

        /// 摘要:

        ///     当指定模型纪录实例需要通过指定查询操作后(默认获取模型纪录的所有实例,即不查询),在页面Jquery DataTabes插件渲染(显示)出来,则通过该类及其属性成员实例实现这些操作。

        ///  注意:

        ///     该纪录是抽象纪录,所以该纪录只能被其它纪录所继承,并由继承纪录所实例化。

        ///

        ///

        public abstract partial record BaseSearchModel :IPagingRequestModel

        {

            #region  拷贝构造方法

            ///

            /// 【拷贝构造方法】

            ///

            /// 摘要:

            ///     实例化该纪录时,该纪录实例默认设置了Jquery DataTabes插件每页最多显示行数为:10行。

            ///

            ///

            protected BaseSearchModel()

            {

                Length = 10;

            }

            #endregion

            #region 属性

            ///

            /// 【页数】

            ///

            /// 摘要:

            ///     获取query DataTable插件当前显示页面的页数值(Jquery DataTable插件默认开始页为:0;而该属性实例则把该默认开始页设置为:1,如果使用默认Jquery DataTable插件,则插件最后页会现“没有匹配结果”异常,即Jquery DataTable插件会多出1页)。

            ///

            ///

            public int Page => (Start / Length) + 1;

            ///

            /// 【页面大小】

            ///

            /// 摘要:

            ///     获取Jquery DataTable插件每页最多的行数值:(弹出窗口默认值)7, (常规页面默认值)15,PageSize>=1。 

            /// 注意:

            ///     该属性为只读属性,该属性的实例值由该类中“Length”属性成员所决定。

            ///

            ///

            public int PageSize => Length;

            ///

            /// 【有效页面大小】

            ///

            /// 摘要:

            ///     获取/设置Jquery DataTable插件以供选择的每页最多显示的行数值,PageSize或Length:(弹出页面默认值)7, (常规页面默认值)15, 20, 50, 100。 

            ///

            ///

            public string AvailablePageSizes { get; set; }

            ///

            /// 【绘制】

            ///

            /// 摘要:

            ///     获取/设置的Jquery DataTable插件在页面中被渲染(显示)出来的次数(当前使用Ajax异步请求操作Jquery DataTable插件时,Jquery DataTable插件可能会不按照顺序返回后台action方法,

            ///     因此必须通过该属性成员实例,来保证按照前台页面的操作顺序,调用后台action方法从而实现Jquery DataTable插件按照该顺序在页面中被渲染(显示)出来)。

            ///

            ///

            public string Draw { get; set; }

            ///

            /// 【开始】

            ///

            /// 摘要:

            ///     获取/设置Jquery DataTable插件当前显示页面,需要跳过的行数值:=(页数-1)*PageSize(或Length:(弹出窗口默认值)7, (常规页面默认值)15, 20, 50, 100),Start>=0。 

            ///

            ///

            public int Start { get; set; }

            ///

            /// 【长度】

            ///

            /// 摘要:

            ///     获取/设置Jquery DataTable插件每页最多的行数值:(弹出窗口默认值)7, (常规页面默认值)15,Length>=1。 

            ///

            ///

            public int Length { get; set; }

            #endregion

            #region 方法

            ///

            /// 【设置页面行数大小】

            ///

            /// 摘要:

            ///     通过下拉控件中的数值动态设置常规页面中Jquery DataTable插件每页最多显示行数,默认值:15行。

            ///

            ///

            public void SetGridPageSize()

            {

                SetGridPageSize(15, "7, 15, 20, 50, 100");

            }

            ///

            /// 【设置弹出页面行数大小】

            ///

            /// 摘要:

            ///    通过下拉控件中的数值动态设置弹出页面中Jquery DataTable插件每页最多显示行数,默认值:7行。

            ///

            ///

            public void SetPopupGridPageSize()

            {

                SetGridPageSize(7, "7, 15, 20, 50, 100");

            }

            /// name="pageSize">Jquery DataTable插件每页最多显示行数值。

            /// name="availablePageSizes">下拉控件中的以供选择的每页最多显示的行数值。

            ///

            /// 【设置页面行数大小】

            ///

            /// 摘要:

            ///    通过下拉控件中的数值动态设置页面中Jquery DataTable插件每页最多显示行数值。

            ///

            ///

            public void SetGridPageSize(int pageSize, string availablePageSizes = null)

            {

                if (availablePageSizes == null)

                    availablePageSizes = "7, 15, 20, 50, 100";

                Start = 0;

                Length = pageSize;

                AvailablePageSizes = availablePageSizes;

            }

            #endregion

        }

    }

    3 StudentSearchModel

    using Microsoft.AspNetCore.Mvc.Rendering;

    using System.ComponentModel.DataAnnotations;

    namespace JsonTable.Models.SearchModel

    {

        ///

        /// 【学生查询模型--纪录】

        ///

        /// 摘要:

        ///     通过学生模型纪录和其基纪录实例对学生实体的所有实例执行查询操作后(默认获取模型纪录的所有实例,即不查询),在页面Jquery DataTabes插件中进行分页渲染(显示)。

        ///

        ///

        public partial record StudentSearchModel : BaseSearchModel

        {

            #region 拷贝构造方法

            ///

            /// 【拷贝构造方法】

            ///

            /// 摘要:

            ///     实例化该纪录时,为列表接口类型的属性成员实例分配内存空间。

            ///

            ///

            public StudentSearchModel()

            {

                SpecialtySelectList = new List();

                GradeSelectList = new List();

                CategorySelectList = new List();

            }

            #endregion

            #region 属性

            ///

            /// 【学号】

            ///

            /// 摘要:

            ///     获取/设置学生实体1个指定实例的学号。

            ///

            ///

            [Display(Name = "学号")]

            public string Code { get; set; }

            ///

            /// 【姓名】

            ///

            /// 摘要:

            ///     获取/设置1个指定学生的姓名。

            ///

            ///

            [Display(Name = "姓名")]

            public string Name { get; set; }

            ///

            /// 【专业编号】

            ///

            /// 摘要:

            ///     获取/设置专业实体1个指定实例的整型编号值。

            ///

            ///

            [Display(Name = "专业")]

            public int SpecialtyId { get; set; }

            ///

            /// 【年级编号】

            ///

            /// 摘要:

            ///     获取/设置年级实体1个指定实例的整型编号值。

            ///

            ///

            [Display(Name = "年级")]

            public int GradeId { get; set; }

            ///

            /// 【班级编号】

            ///

            /// 摘要:

            ///     获取/设置班级实体1个指定实例的整型编号值。

            ///

            ///

            [Display(Name = "班级")]

            public int CategoryId { get; set; }

            ///

            /// 【专业选择列表实例】

            ///

            /// 摘要:

            ///     获取/设置把专业实体的所有下拉列表实例,存储到列表接口实例中。

            ///

            ///

            public IList SpecialtySelectList { get; set; }

            ///

            /// 【年级选择列表实例】

            ///

            /// 摘要:

            ///     获取/设置把年级实体的所有下拉列表实例,存储到列表接口实例中。

            ///

            ///

            public IList GradeSelectList { get; set; }

            ///

            /// 【班级选择列表实例】

            ///

            /// 摘要:

            ///     获取/设置把班级实体的所有下拉列表实例,存储到列表接口实例中。

            ///

            ///

            public IList CategorySelectList { get; set; }

            #endregion

        }

    }

    4 StudentController

    namespace JsonTable.Controllers

    {

        public class StudentController : Controller

        {

            private readonly EFCoreContext _context;

            public StudentController(EFCoreContext context)

            {

                _context = context;

            }

            #region 方法--私有/保护

            /// name="studentSearchModel">1个指定的学生查询模型实例。

            ///

            /// 【预处理学生查询模型】

            ///

            /// 摘要:

            ///     通过参数实例,初始化设置页面中的查询表单和Jquery DataTable插件。

            ///

            ///

            protected virtual StudentSearchModel PrepareStudentSearchModel(StudentSearchModel studentSearchModel)

            {

                PrepareSpecialty(studentSearchModel.SpecialtySelectList);

                PrepareGrade(studentSearchModel.GradeSelectList);

                PrepareCategory(studentSearchModel.CategorySelectList);

                //初始化设置页面行下拉控件,动态设置常规页面中Jquery DataTable插件每页最多显示行数,默认值:15行。

                studentSearchModel.SetGridPageSize();

                return studentSearchModel;

            }

            /// name="selectListItemList">1个指定的存储着1/多个下拉控件项的列表实例。

            /// name="withSpecialDefaultItem">指示是否允许向1个指定的存储着1/多个下拉控件项的列表实例中,添加1个指定的下拉控件项实例。

            /// name="defaultItemText">1个指定下拉控件项所对应的默认文本值,该参数默认值:null(则默认文本值为:"全部")。

            /// name="defaultItemValue">1个指定下拉控件项所对应的默认值,该参数默认值:0。

            /// name="studentSearchModel">1个指定的学生查询模型实例。

            ///

            /// 【预处理下拉控件项的列表实例】

            ///

            /// 摘要:

            ///     通过参数实例,把1个指定下拉控件项实例,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

            ///

            ///

            protected virtual void PrepareDefaultItem(IList selectListItemList, bool withSpecialDefaultItem, string defaultItemText = null, string defaultItemValue = "0")

            {

                if (selectListItemList == null)

                    throw new ArgumentNullException(nameof(selectListItemList));

                //如果不允许向指定的下拉控件中,则直接推出该方法。

                if (!withSpecialDefaultItem)

                    return;

                //1个指定下拉控件项所对应的默认文本值,该参数默认值:null(则默认文本值为:"全部")。

                defaultItemText ??= "全部";

                //把1个指定下拉控件项实例,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

                selectListItemList.Insert(0, new SelectListItem { Text = defaultItemText, Value = defaultItemValue });

            }

            ///

            /// 【获取专业下拉控件项的列表实例】

            ///

            /// 摘要:

            ///     把专业实体的所有实例中的指定值,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

            ///

            ///

            protected virtual List GetSpecialtySelectListItem()

            {

                List _specialtyList = _context.SpecialtyDbSet.ToList();

                return _specialtyList.Select(specialty => new SelectListItem

                {

                    Text = specialty.Name,

                    Value = specialty.Id.ToString()

                }).ToList();

            }

            /// name="selectListItemList">1个指定的存储着1/多个下拉控件项的列表实例。

            /// name="withSpecialDefaultItem">指示是否允许向1个指定的存储着1/多个下拉控件项的列表实例中,添加1个指定的下拉控件项实例。

            /// name="defaultItemText">1个指定下拉控件项所对应的默认文本值,该参数默认值:null(则默认文本值为:"全部")。

            ///

            /// 【预处理专业下拉控件项的列表实例】

            ///

            /// 摘要:

            ///     通过参数实例,把专业下拉控件项的所有实例,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

            ///

            ///

            public virtual void PrepareSpecialty(IList selectListItemList, bool withSpecialDefaultItem = true, string defaultItemText = null)

            {

                if (selectListItemList == null)

                    throw new ArgumentNullException(nameof(selectListItemList));

                //把专业实体的所有实例,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

                List _specialtySelectList = GetSpecialtySelectListItem();

                foreach (var itme in _specialtySelectList)

                {

                    selectListItemList.Add(itme);

                }

                //把1个指定下拉控件项实例,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

                PrepareDefaultItem(selectListItemList, withSpecialDefaultItem, defaultItemText);

            }

            ///

            /// 【获取年级下拉控件项的列表实例】

            ///

            /// 摘要:

            ///     把年级实体的所有实例中的指定值,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

            ///

            ///

            protected virtual List GetGradeSelectListItem()

            {

                List _gradeList = _context.GradeDbSet.ToList();

                return _gradeList.Select(grade => new SelectListItem

                {

                    Text = grade.Name,

                    Value = grade.Id.ToString()

                }).ToList();

            }

            /// name="selectListItemList">1个指定的存储着1/多个下拉控件项的列表实例。

            /// name="withSpecialDefaultItem">指示是否允许向1个指定的存储着1/多个下拉控件项的列表实例中,添加1个指定的下拉控件项实例。

            /// name="defaultItemText">1个指定下拉控件项所对应的默认文本值,该参数默认值:null(则默认文本值为:"全部")。

            ///

            /// 【预处理年级下拉控件项的列表实例】

            ///

            /// 摘要:

            ///     通过参数实例,把年级下拉控件项的所有实例,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

            ///

            ///

            public virtual void PrepareGrade(IList selectListItemList, bool withSpecialDefaultItem = true, string defaultItemText = null)

            {

                if (selectListItemList == null)

                    throw new ArgumentNullException(nameof(selectListItemList));

                //把年级实体的所有实例,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

                List _gradeSelectList = GetGradeSelectListItem();

                foreach (var itme in _gradeSelectList)

                {

                    selectListItemList.Add(itme);

                }

                //把1个指定下拉控件项实例,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

                PrepareDefaultItem(selectListItemList, withSpecialDefaultItem, defaultItemText);

            }

            /// name="gradeId">年级实体1个指定实例的整型编号值。

            ///

            /// 【获取班级下拉控件项的列表实例】

            ///

            /// 摘要:

            ///     把班级实体的所有满足条件实例中的指定值,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

            ///

            ///

            protected virtual List GetCategorySelectListItem(int? gradeId = 0)

            {

                IQueryable _categoryIqueryable = _context.CategoryDbSet;

                if (gradeId != null && gradeId != 0)

                    _categoryIqueryable = _categoryIqueryable.Where(c => c.GradeId == gradeId);

                List _categoryList = _categoryIqueryable.ToList();

                return _categoryList.Select(category => new SelectListItem

                {

                    Text = category.Name,

                    Value = category.Id.ToString()

                }).ToList();

            }

            /// name="gradeId">年级实体1个指定实例的整型编号值。

            /// name="selectListItemList">1个指定的存储着1/多个下拉控件项的列表实例。

            /// name="withSpecialDefaultItem">指示是否允许向1个指定的存储着1/多个下拉控件项的列表实例中,添加1个指定的下拉控件项实例。

            /// name="defaultItemText">1个指定下拉控件项所对应的默认文本值,该参数默认值:null(则默认文本值为:"全部")。

            ///

            /// 【预处理班级下拉控件项的列表实例】

            ///

            /// 摘要:

            ///     通过参数实例,把班级下拉控件项的所有实例,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

            ///

            ///

            public virtual void PrepareCategory(IList selectListItemList, int? gradeId = 0, bool withSpecialDefaultItem = true, string defaultItemText = null)

            {

                if (selectListItemList == null)

                    throw new ArgumentNullException(nameof(selectListItemList));

                //把班级实体的所有满足条件实例中的指定值,添加到1个指定的存储着1 / 多个下拉控件项的列表实例中。

                List _categorySelectList = GetCategorySelectListItem(gradeId);

                foreach (var itme in _categorySelectList)

                {

                    selectListItemList.Add(itme);

                }

                //把1个指定下拉控件项实例,添加到1个指定的存储着1/多个下拉控件项的列表实例中。

                PrepareDefaultItem(selectListItemList, withSpecialDefaultItem, defaultItemText);

            }

            #endregion

            public IActionResult Index()

            {

                StudentSearchModel _model = PrepareStudentSearchModel(new StudentSearchModel());

                return View(_model);

            }

            #region 方法--Ajax

            /// name="gradeId">年级实体1个指定实例的整型编号值。

            ///

            /// 【班级下拉控件局部刷新】

            ///

            /// 摘要:

            ///     通过参数实例,实现年级下拉框控件联动局部刷新班级下拉框控件。

            ///

            ///

            public IActionResult CategorySelectListAjax(int? gradeId = 0)

            {

                StudentSearchModel studentSearchModel = new StudentSearchModel();

                PrepareCategory(studentSearchModel.CategorySelectList, gradeId);

                return Json(studentSearchModel.CategorySelectList);

            }

            #endregion

        }

    }

    4  Index.cshtml

    @model JsonTable.Models.SearchModel.StudentSearchModel

    @{

        ViewData["Title"] = "Index";

    }

     <form asp-action="Index">

        <div class="content-header clearfix">

            <h1 class="float-left">

                学生

            h1>

            <div class="float-right">

                <button type="button" id="resetStudent" class="btn btn-secondary me-3">

                    <i class="fa-solid fa-rotate-right">i>

                    重置

                button>

                <a asp-action="Create" class="btn btn-primary  me-3">

                    <i class="fas fa-plus-square">i>

                    添加

                a>

                <button type="button" id="delete-selected" class="btn btn-danger">

                    <i class="far fa-trash-alt">i>

                    删除所选

                button>

            div>

        div>

        <div class="card card-primary card-outline">

            <div class="card-body">

                <div class="row">

                    <div class="card-title">

                        <i class="fas fa-search" aria-hidden="true">i> 搜索

                    div>

                div>

              

                <div class="row mt-3">

                    <div class="col-md-6">

                        <div class="form-group row">

                            <div class="col-md-4 text-right">

                                <label asp-for="Code" class="col-form-label">label>

                            div>

                            <div class="col-md-8">

                                <input asp-for="Code" class="form-control" />

                            div>

                        div>

                      

                        <div class="form-group row">

                            <div class="col-md-4 text-right">

                                <label asp-for="SpecialtyId" class="col-form-label">label>

                            div>

                            <div class="col-md-8">

                                <select asp-for="SpecialtyId" class="form-select" asp-items="Model.SpecialtySelectList">select>

                            div>

                        div>

                        <div class="form-group row d-none" id="categoryRow">

                            <div class="col-md-4 text-right">

                                <label asp-for="CategoryId" class="col-form-label">label>

                            div>

                            <div class="col-md-8">

                                <select asp-for="CategoryId" class="form-select" asp-items="Model.CategorySelectList">select>

                            div>

                        div>

                       

                    div>

                    <div class="col-md-6">

                        <div class="form-group row">

                            <div class="col-md-4 text-right">

                                <label asp-for="Name" class="col-form-label">label>

                            div>

                            <div class="col-md-8">

                                <input asp-for="Name" class="form-control" />

                            div>

                        div>

                        <div class="form-group row">

                            <div class="col-md-4 text-right">

                                <label asp-for="GradeId" class="col-form-label">label>

                            div>

                            <div class="col-md-8">

                                <select asp-for="GradeId" class="form-select" asp-items="Model.GradeSelectList">select>

                            div>

                        div>

                    div>

                div>

                <div class="row mt-3">

                    <div class="text-center col-12">

                        <button type="button" id="search-products" class="btn btn-primary btn-search">

                            <i class="fas fa-search">i>

                            搜索

                        button>

                    div>

                div>

            div>

            div>

        <div class="card card-primary card-outline">

            <div class="card-body">

                <div class="row">

                    <div class="card-title">

                        <i class="fas fa-list" aria-hidden="true">i> 表单

                    div>

                div>

                <div class="row mt-3">

                   

                div>

            div>

        div>

    form>

    @section Scripts

    {

        @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}

        <script type="text/javascript">

            $(function ()

            {

                //年级下拉框控件联动局部刷新班级下拉框控件。

                $("#GradeId").change(function ()

                {

                    var selectedItem = $(this).val();

              

                    $.ajax({

                        url: "/Student/CategorySelectListAjax",

                        type: "GET",

                        datatype: "JSON",

                        cache: false//禁用缓存。

                       

                        data:

                        {

                            "gradeId": selectedItem

                        },

                        success: function (data)

                        {

                            if (selectedItem == 0)

                            {

                                $("#categoryRow").addClass('d-none'); // 隐藏

                            }

                            else

                            {

                                $("#categoryRow").removeClass('d-none'); //显示

                            }

                          

                            $('#CategoryId').empty();

                            $.each(data,

                                function (id, option) {

                                    $('#CategoryId').append($('').val(option.value).html(option.text));

                                });

                        }

                    });

                });

            });

        script>

    }

    对以上功能更为具体实现和注释见:22-09-06-067_JsonTable(完整定义nopCommerce Jquery DataTable插件之初始化查询表单)。

  • 相关阅读:
    VUE基础知识五:组件的分类、组件间传值、事件调用等
    论文笔记:Large Language Model for Participatory Urban Planning
    不定积分第一类换元法(凑微分法)
    10.网络游戏逆向分析与漏洞攻防-游戏网络架构逆向分析-接管游戏发送数据的操作
    使用文本分析识别一段文本中的主要性别
    Linux进程间通信模式
    [Linux](1)Linux入门环境搭建|云服务器|Xshell远程登陆|Xshell复制粘贴|用户管理
    Java集合学习详解(2023年史上最全版)
    Day 52 | 674. 最长连续递增序列 & 718. 最长重复子数组 & 1143.最长公共子序列
    Docker 镜像常用命令总结
  • 原文地址:https://blog.csdn.net/zhoujian_911/article/details/126722699