• 父类和子类在同一张表


    现在出现了父类和子类一般都会存在一张表中,然后设计数据库的时候把父类的ID存到子类另一个字段中就实现了关联。

    例如: 网站的左边导航     第一层就可以看做父类,里面就可以看做子类。

    我们就先来看看怎么做导航。

    效果图:

     

    一切为了用户,这个只显示一个下面出来,不要显示多个不然很难看

    ① 前台页面

     <div >
            <ul id="test" >
            <asp:Repeater ID="replist" runat="server" OnItemDataBound="replist_ItemDataBound">
                <ItemTemplate>
                <li>
                    <a class="one" href="javascript:void()"><em><%# Eval("Name")%></em></a>
                    <ul style="display: none;">
                        <asp:HiddenField ID="hfId" runat="server" Value='<%# Eval("ID") %>' />
                        <asp:Literal ID="LitFirst" runat="server"></asp:Literal>    //这个标签用来替换数据
                    </ul>
                </li>
                </ItemTemplate>
            </asp:Repeater>
            </ul>
        </div>
            <script src="../JS/jquery-1.11.0.min.js"></script>
            <script>
                $("ul#test").on("click", "li", function () {
                    //$("ul li ul").css("display", "none");
                    if ($(this).hasClass("show")) {
                        $("ul#test li").removeClass("show");
                        Test();
                        //$(this).removeClass("show");
                      //  $(this).find("ul").css("display", "none");
                    } else {
                        $("ul#test li").removeClass("show");
                        $(this).addClass("show");
                       Test();
                        //$(this).find("ul").css("display", "block");
                    }
                });
              //用来隐藏和显示下面的数据
                function Test()
                {
                    $("ul#test li").each(function () {
                        if ($(this).hasClass("show")) {
                            $(this).find("ul").css("display", "block");
                        } else {
                            $(this).find("ul").css("display", "none");
                        }
                    });
                }
            </script>

    ②样式  简单设置一下

        <style>
            ul {
                list-style:none;
            }
            em {
                    font-style: normal;
            }
            a {text-decoration:none;
            }
        </style>

    ③取数据    由于我们搭建的div的原因,想要显示出所有的数据需要用到Repter里面的数据绑定事件

     protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    Binging();
                }
            }
    
            private void Binging()
            {
                DataSet ds = new FunctionDemo.BLL.Category().GetList("Pid=0");
                replist.DataSource = ds.Tables[0];
                replist.DataBind();
            }
    
            /// <summary>
            /// 每绑定一行就触发一次  一般这个方法用来加载每一行的子类数据
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected void replist_ItemDataBound(object sender, RepeaterItemEventArgs e)
            {           
                Literal LitFirst = (Literal)e.Item.FindControl("LitFirst");
                HiddenField hfId = (HiddenField)e.Item.FindControl("hfId");
                List<FunctionDemo.Model.Category> cateModel = new FunctionDemo.BLL.Category().GetModelList("Pid=" + hfId.Value);
    
                foreach (FunctionDemo.Model.Category item in cateModel)
                {
                    LitFirst.Text = LitFirst.Text + "<li>"+item.Name+"</li>";
                }
            }

    ④数据的设计  

    父类 Pid=0 子类的Pid就是父类的ID    LevalNum用来表示

    第一种父子类就说到这,下面说的是第二种方式 

    其中的有个方法值得学习下

     

    我们换成下拉框来试试    按分类显示数据  列: 父类 子类   父类  子类  。。

    ①页面

     <form id="form1" runat="server">
            <asp:DropDownList ID="ddlDemo" runat="server"></asp:DropDownList>
        </form>

    ②代码

       public FunctionDemo.BLL.Category categoryBLL = new FunctionDemo.BLL.Category();
            protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    BingDDL();
                }
            }
    
            public void BingDDL()
            {
                DataTable dt = categoryBLL.GetList("").Tables[0];       //categoryBLL.GetListChild(0, true);
                ddlDemo.Items.Add(new ListItem("类别", "0"));
                foreach (DataRow item in dt.Rows)
                {
                    string title = "";
                    if (int.Parse(item["LevalNum"].ToString()) > 0)
                    {
                        title =" " + "|--" + item["Name"].ToString();
                    }
                    else
                    {
                        title = item["Name"].ToString();
                    }
                    ddlDemo.Items.Add(new ListItem(title, item["ID"].ToString()));
                }
    
            }

    ③显示效果

    这一切尽是如此的完美,好像很好一样的。

    我们做项目时并不是说所以的东西都是好的,很可能做了一半让你加几条数据,我们来试一试  NBA 加一条 ,爱好加一条,别找我加一条

     我们的数据

    然后再显示

    我们如何把NBA子类往上面移动呢,这是问题的关键,那么就是查询数据的问题了。

    我们改动了取数据的方法

    然后显示数据 

     这样很符合我们的要求。

    我们来看看这个方法写了什么。

      /// <summary>
            /// 获取全部类别
            /// </summary>
            /// <param name="strWhere">后面的bool值可以显示是否显示禁用的数据,这里并没做处理</param>
            /// <returns></returns>
            public DataTable GetListChild(int PID, bool isState)
            {
                StringBuilder strSql = new StringBuilder();
                strSql.Append("select ID,Name,Pid,LevalNum");
                strSql.Append(" FROM Category ");
                //strSql.Append(" Where ParentId=" + PId);
                if (isState)
                {
                    strSql.Append("Where 1=1 ");
                }
                strSql.Append(" order by Id asc");
                DataSet ds = DbHelperSQL.Query(strSql.ToString());      我们的数据查找完了,跟以前是一样的
                DataTable oldData = ds.Tables[0] as DataTable;
                if (oldData == null)
                {
                    return null;
                }
                //复制结构
                DataTable newData = oldData.Clone();       clone()是基类Object的方法
                //调用迭代组合成DAGATABLE   用旧数据得到新数据
                GetChannelChild(oldData, newData, PID);
    
                return newData;
            }
    
    
            /// <summary>
            /// 获取子类别
            /// </summary>
            /// <param name="parentId">父编号</param>
            /// <param name="stateInfo">状态</param>
            /// <returns></returns>
            private void GetChannelChild(DataTable oldData, DataTable newData, int PId)
            {
                //第一遍进来的时候是获取父类 pid=0      我们只需每取一条父类数据,然后把改类的子类数据先加载进去就可以了
                DataRow[] dr = oldData.Select("Pid=" + PId);
                for (int i = 0; i < dr.Length; i++)
                {
                    //添加一行数据 
                    DataRow row = newData.NewRow();  
                    row["ID"] = int.Parse(dr[i]["ID"].ToString());
                    row["Name"] = dr[i]["Name"].ToString();
                    row["Pid"] = dr[i]["Pid"].ToString();
                    row["LevalNum"] = dr[i]["LevalNum"].ToString();               
                    newData.Rows.Add(row);
                    //调用自身迭代
                    this.GetChannelChild(oldData, newData, int.Parse(dr[i]["ID"].ToString()));
                    //把父类的ID作为条件传进去,子类的数据就会出来
                }
            }

    这个方法是一种思想,会的话可以做别的事。

    上面是满足我们的原数据和新数据都是在一张表,我们就可以用clone()方法,如果我的新表需要添加字段

       //创建一个新的DataTable,这里可以添加我们的列
                DataTable newData = new DataTable();
                newData.Columns.Add("id", typeof(int));
                newData.Columns.Add("parent_id", typeof(int));
                newData.Columns.Add("class_layer", typeof(int));
                newData.Columns.Add("nav_type", typeof(string));
                newData.Columns.Add("name", typeof(string));
                newData.Columns.Add("title", typeof(string));
                newData.Columns.Add("sub_title", typeof(string));
                newData.Columns.Add("icon_url", typeof(string));
                newData.Columns.Add("link_url", typeof(string));
                newData.Columns.Add("sort_id", typeof(int));
                newData.Columns.Add("is_lock", typeof(int));
                newData.Columns.Add("remark", typeof(string));
                newData.Columns.Add("action_type", typeof(string));
                newData.Columns.Add("is_sys", typeof(int));
                 //调用迭代组合成DAGATABLE   用旧数据得到新数据
                GetChannelChild(oldData, newData, PID);
    
                 return newData;
              //在GetChannelChild()这个方法里面的添加数据里面就可以把新列的数据添加进去
  • 相关阅读:
    常见错误--06.18
    类目-延展-协议
    iOS页面传值-wang
    ios常见的页面传值方式
    delegate和protocol
    沙盒路径及文件 操作
    tableView优化性能
    IOS面试题
    浅谈Runloop
    面试题
  • 原文地址:https://www.cnblogs.com/Sea1ee/p/7028595.html
Copyright © 2020-2023  润新知