重复控件Repeater和数据列表控件DataList

5.3  重复控件Repeater和数据列表控件DataList

本节介绍ASP.NET中两个数据迭代控件:Repeater和DataList控件。其中,Repeater控件又被称为重复控件;DataList控件又被称为数据列表控件。它们都可以以表格形式显示数据。

5.3.1  Repeater控件概述

Repeater控件是一个数据容器控件,它能够以表格形式显示数据源的数据。若该控件的数据源为空,则什么都不显示。该控件允许用户创建自定义列,并且还能够为这些列提供布局,然而,Repeater控件本身不提供内置呈现功能。若该控件需要呈现数据,则必须为其提供相应的布局。Repeater控件的属性如表5-12所示。

表5-12                                                       Repeater控件的属性

属    性

描    述

DataSource

数据源

DataSourceID

数据源控件的ID属性,控件从该数据源控件检索数据

DataMember

DataSource属性中要绑定到控件的数据成员

Items

RepeaterItem对象的集合

Controls

子控件集合

EnableTheming

是否应用主题

Repeater控件可以通过DataSourceID、DataSource或DataMember属性来设置其数据源。其中,DataSourceID属性为数据源控件的ID属性值。若Repeater控件使用数据源控件提供数据,它不需要显示绑定控件的数据。DataSource属性可以直接作为Repeater控件的数据源,但是需要显示调用DataBind()方法绑定Repeater控件的数据。另外,若DataSource属性包含多个数据成员,则还可以使用DataMember属性指定DataSource属性中的一个数据成员为Repeater控件的数据源。

Repeater控件还提供了3个事件:ItemCommand、ItemCreated和ItemDataBound,说明如表5-13所示。

表5-13                                                       Repeater控件的事件

事    件

描    述

ItemCommand

单击控件中的按钮时发生

ItemCreated

控件中的项创建时发生

ItemDataBound

控件中的项被数据绑定之后发生

5.3.2  DataList控件概述

DataList控件也是一种迭代控件。它不但可以以某种格式重复显示数据,而且还能够将样式应用这些数据,另外,DataList控件还可以控制数据显示的方向。和Repeater控件一样,DataList控件也支持模板,并且还为这些模板提供相应的样式。

DataList控件提供了5个静态只读字段,它们分别表示选择、编辑、更新、取消和删除命名的名称,如表5-14所示。

表5-14                                                       DataList控件的字段

字    段

描    述

SelectCommandName

【选择】命令名,只读字段

EditCommandName

【编辑】命令名,只读字段

UpdateCommandName

【更新】命令名,只读字段

CancelCommandName

【取消】命令名,只读字段

DeleteCommandName

【删除】命令名,只读字段

DataList控件提供了大量的属性,这些属性可以设置控件的行为、样式、外观等,如表5-15所示。

表5-15                                                       DataList控件的属性

属    性

描    述

EditItemIndex

编辑项的索引

SelectedIndex

选定项的索引

SelectedItem

选定项

SelectedValue

选定项的键字段的值

Items

控件的项集合,该集合的每一个元素类型为DataListItem

RepeatLayout

控件的重复模式,可以是表格形式或流形式

GridLines

网格线样式

RepeatColumns

控件重复显示的列数

RepeatDirection

控件是垂直显示还是水平显示

ShowHeader

控件是否显示页眉部分

ShowFooter

控件是否显示脚注部分

下面的实例代码在DatalistCtl.aspx页面上声明了一个DataList控件和一个SqlDataSource数据源控件,它们的ID属性的值分别为dlUser和myDSUser。其中,myDSUser控件为dlUser的数据源控件,并为该控件提供数据。

<!-- Sample_05_03的DatalistCtl.aspx页面 -->

<%@ Page Language="C#" %>

<script runat="server"></script>

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server"><title>DataList控件的模板列</title></head>

<body><form id="form1" runat="server">

<asp:DataList ID="dlUser" runat="server" BackColor="White"

    BorderColor="#336666" BorderStyle="Double" BorderWidth="3px"

    CellPadding="4" DataKeyField="ID" DataSourceID="myDSUser"

    GridLines="Horizontal" Font-Size="9pt" RepeatColumns="5">

注意

下述HTML代码创建DataList控件的一个交替模板列,并在该列中显示用户的ID值、名称、电子邮件等信息。

        <AlternatingItemTemplate>

            ID:<asp:Label ID="IDLabel" runat="server" Text='<%# Eval("ID")

            %>'></asp:Label><br />

            UserName:<asp:Label ID="UserNameLabel" runat="server" Text='<%#

            Eval("UserName") %>'></asp:Label><br />

            Email:<asp:Label ID="EmailLabel" runat="server" Text='<%#

            Eval("Email") %>'></asp:Label><br />

            CreateDate:<asp:Label ID="CreateDateLabel" runat="server" Text='<%#

            Eval("CreateDate") %>'></asp:Label><br /><br />

       </AlternatingItemTemplate>

注意

下述HTML代码创建DataList控件的一个项模板列,并在该列中显示用户的ID值、名称、电子邮件等信息。

    <ItemTemplate>

        ID:<asp:Label ID="IDLabel" runat="server" Text='<%# Eval("ID")

        %>'></asp:Label><br />

        UserName:<asp:Label ID="UserNameLabel" runat="server" Text='<%#

        Eval("UserName") %>'></asp:Label><br />

        Email:<asp:Label ID="EmailLabel" runat="server" Text='<%#

        Eval("Email") %>'></asp:Label><br />

        CreateDate:<asp:Label ID="CreateDateLabel" runat="server" Text='<%#

        Eval("CreateDate") %>'></asp:Label><br /><br />

    </ItemTemplate>

</asp:DataList>

<asp:SqlDataSource ID="myDSUser" runat="server" ConnectionString="<%$

    ConnectionStrings:WEB2ASPNET2DBConnectionString %>"

    SelectCommand="SELECT [ID], [UserName], [Email], [CreateDate]

        FROM [User]"></asp:SqlDataSource>

</form></body>

</html>

上述代码实例的执行结果如图5.19所示。

图5.19  DataList控件显示数据

5.3.3  Repeater控件的模板

Repeater控件支持5种模板:HeaderTemplate、FooterTemplate、AlternatingItemTemplate、ItemTemplate和SeparatorTemplate,它们的具体说明如表5-16所示。

表5-16                                                       Repeater控件的模板

模 板 名 称

描    述

ItemTemplate

项模板,定义如何显示控件中的项

AlternatingItemTemplate

交替项模板,定义如何显示控件中的交替项

HeaderTemplate

头模板,定义如何显示控件的标头部分

FooterTemplate

脚注模板,定义如何显示控件的注脚部分

SeparatorTemplate

分割模板,定义如何显示各项之间的分隔符

HeaderTemplate和FooterTemplate模板分别在Repeater控件的开始和结束处呈现文本和控件。ItemTemplate和AlternatingItemTemplate(如果存在)模板交替呈现Repeater控件的数据源中的数据项。如果不存在AlternatingItemTemplate模板,则重复显示ItemTemplate模板的内容。SeparatorTemplate模板是ItemTemplate之间、AlternatingItemTemplate之间或者两者之间的分割项。

下面的代码实例声明了一个Repeater控件,该控件使用了HeaderTemplate、ItemTemplate和FooterTemplate。另外,该控件使用SqlDataSource控件作为数据源,显示用户表User中的记录。

该Repeater控件还定义了ItemDataBound事件,名称为rpUser_ItemDataBound(object sender, RepeaterItemEventArgs e)。该事件设置控件中每一个数据项的编号。

<!-- Sample_05_03的RepeaterCtl.aspx页面 -->

<%@ Page Language="C#" %>

<script runat="server">

protected void rpUser_ItemDataBound(object sender,RepeaterItemEventArgs e)

{

    if(e.Item.ItemType == ListItemType.Item

        || e.Item.ItemType == ListItemType.AlternatingItem)

    {   ///找到lbNumber控件,并设置它的编号

        Label lbNumber = (Label)e.Item.FindControl("lbNumber");

        if(lbNumber != null)

        {

            lbNumber.Text = (e.Item.ItemIndex + 1).ToString();

        }

    }

}

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server"><title>Repeater控件的模板列</title></head>

<body><form id="form1" runat="server">

<asp:Repeater ID="rpUser" runat="server"

    OnItemDataBound="rpUser_ItemDataBound" DataSourceID="myDSUser">

注意

下述HTML代码创建Repeater控件的一个HeaderTemplate模板,并在该模板显示表格的表头。

    <HeaderTemplate>

        <table border="1">

            <tr>

                <td>编号</td>

                <td>用户ID</td>

                <td>用户名称</td>

                <td>电子邮件</td>

            </tr>

    </HeaderTemplate>

注意

下述HTML代码创建Repeater控件的一个ItemTemplate模板,并在该模板显示表格的每一个数据行。

    <ItemTemplate>

            <tr>

                <td><asp:Label ID="lbNumber" runat="server">

                    </asp:Label></td>

                <td><%# Eval("ID")%></td>

                <td><%# Eval("UserName").ToString() %></td>

                <td><%# Eval("Email").ToString() %></td>

            </tr>

    </ItemTemplate>

注意

下述HTML代码创建Repeater控件的一个FooterTemplate模板,并在该模板显示表格的表尾。

    <FooterTemplate>

        </table>

    </FooterTemplate>

</asp:Repeater>

<asp:SqlDataSource ID="myDSUser" runat="server" ConnectionString="<%$

    ConnectionStrings:WEB2ASPNET2DBConnectionString %>"

    SelectCommand="SELECT [ID], [UserName], [Email], [CreateDate]

        FROM [User]"></asp:SqlDataSource>

</form></body>

</html>

上述代码实例的执行结果如图5.20所示。

图5.20  Repeater控件的模板显示数据

5.3.4  DataList控件的模板

DataList控件支持7种模板:HeaderTemplate、FooterTemplate、AlternatingItemTemplate、ItemTemplate、EditItemTemplate、SelectedItemTemplate和SeparatorTemplate,它们的具体说明如表5-17所示。

表5-17                                                       DataList控件的模板

模板或样式名称

描    述

ItemTemplate

项的模板

AlternatingItemTemplate

交替项的模板

EditItemTemplate

编辑项的模板

HeaderTemplate

标题部分的模板

FooterTemplate

脚注部分的模板

SelectedItemTemplate

选定项的模板

SeparatorTemplate

各项间分隔项的模板

ItemStyle

项的样式属性

AlternatingItemStyle

交替项的样式属性

EditItemStyle

编辑项的样式属性

HeaderStyle

标题部分的样式属性

FooterStyle

脚注部分的样式属性

SelectedItemStyle

选定项的样式属性

SeparatorStyle

各项间分隔项的样式属性

HeaderTemplate和FooterTemplate模板分别呈现DataList控件的标题部分和脚注部分。ItemTemplate和AlternatingItemTemplate(如果存在)模板交替呈现DataList控件的数据源中的数据项。如果不存在AlternatingItemTemplate模板,则重复显示ItemTemplate模板的内容。

SeparatorTemplate模板是ItemTemplate之间、AlternatingItemTemplate之间或者两者之间的分隔项。SelectedItemTemplate模板呈现控件中被选中的项的数据或控件。EditItemTemplate模板呈现控件的编辑项的数据或控件。另外,DataList控件还为上述7个模板提供了相应的样式,具体描述如下。

*     HeaderStyle,标题项样式,应用于HeaderTemplate模板。

*     ItemStyle,普通项样式,应用于ItemTemplate模板。

*     AlternatingItemStyle,交替项样式,应用于AlternatingItemTemplate模板。

*     SeparatorStyle,分隔项样式,应用于SeparatorTemplate模板。

*     EditItemStyle,编辑项样式,应用于EditItemTemplate模板。

*     SelectedItemStyle,选定项样式,应用于SelectedItemTemplate模板。

*     FooterStyle,脚注项样式,应用于FooterTemplate模板。

下面的代码实例声明了一个DataList控件,它的ID属性值为dlUser。该控件使用了4种模板:HeaderTemplate、ItemTemplate、AlternatingItemTemplate和FooterTemplate。该控件使用SqlDataSource控件myDSUser作为数据源,显示用户表User中的记录。

另外,该控件还定义了ItemDataBound事件,名称为dlUser_ItemDataBound(object sender, DataListItemEventArgs e),该事件设置控件中每一个数据项的编号。

<!-- Sample_05_03的DLColumn.aspx页面 -->

<%@ Page Language="C#" %>

<script runat="server">

protected void dlUser_ItemDataBound(object sender,DataListItemEventArgs e)

{

    if(e.Item.ItemType == ListItemType.AlternatingItem

        || e.Item.ItemType == ListItemType.Item)

    {   ///找到lbNumber控件,并设置它的编号

        Label lbNumber = (Label)e.Item.FindControl("lbNumber");

        if(lbNumber != null)

        {

            lbNumber.Text = (e.Item.ItemIndex + 1).ToString();

        }

    }

}

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server"><title>DataList控件的模板列</title></head>

<body><form id="form1" runat="server">

<asp:DataList ID="dlUser" runat="server" BackColor="White"

    BorderStyle="Double" BorderWidth="3px" CellPadding="4"

    DataKeyField="ID" DataSourceID="myDSUser" GridLines="Horizontal"

    Font-Size="9pt" OnItemDataBound="dlUser_ItemDataBound"

    RepeatDirection="Horizontal">

注意

下述HTML代码创建DataList控件的一个HeaderTemplate模板,并在该模板显示表格的表头。

    <HeaderTemplate>

        <table border="1">

            <tr>

                <td>编号</td>

                <td>用户ID</td>

                <td>用户名称</td>

                <td>电子邮件</td>

            </tr>

    </HeaderTemplate>

注意

下述HTML代码创建DataList控件的一个ItemTemplate模板,并在该模板显示表格的表头。

    <ItemTemplate>

            <tr>

                <td><asp:Label ID="lbNumber" runat="server">

                     </asp:Label></td>

                <td><%# Eval("ID")%></td>

                <td><%# Eval("UserName").ToString() %></td>

                <td><%# Eval("Email").ToString() %></td>

            </tr>

    </ItemTemplate>

注意

下述HTML代码创建DataList控件的一个AlternatingItemTemplate模板,并在该模板显示表格的表头。

    <AlternatingItemTemplate>

            <tr>

                <td><asp:Label ID="lbNumber" runat="server">

                    </asp:Label></td>

                <td><%# Eval("ID")%></td>

                <td><%# Eval("UserName").ToString() %></td>

                <td><%# Eval("Email").ToString() %></td>

            </tr>

    </AlternatingItemTemplate>

注意

下述HTML代码创建DataList控件的一个FooterTemplate模板,并在该模板显示表格的表头。

    <FooterTemplate>

        </table>

    </FooterTemplate>

</asp:DataList>

<asp:SqlDataSource ID="myDSUser" runat="server" ConnectionString="<%$

    ConnectionStrings:WEB2ASPNET2DBConnectionString %>"

    SelectCommand="SELECT [ID], [UserName], [Email], [CreateDate]

        FROM [User]"></asp:SqlDataSource>

</form></body>

</html>

上述代码实例的执行结果如图5.21所示。

图5.21  DataList控件的模板显示数据

5.3.5  获取CommandArgument属性的值

按钮控件(如Button、ImageButton、LinkButton等)包括两个属性:CommandArgument和CommandName。其中,第一个属性用来保存操作所需要的参数,第二个属性用来保存执行操作的标识。

注意

CommandArgument和CommandName属性一般应用在控件的Command事件中。

若DataList控件的项中包含了按钮控件,当用户单击按钮控件时,会触发DataList控件的ItemCommand事件。该事件的参数e的CommandArgument和CommandName属性的值分别等于该按钮的CommandArgument和CommandName属性的值。

下面的代码实例首先判断参数e的CommandName属性的值是否为“show”,如果是,则显示该参数的CommandArgument属性的值。

protected void dlUser_ItemCommand(object source,

    DataListCommandEventArgs e)

{   ///获取CommandName属性的值

    if(e.CommandName.ToLower() == "show")

    {   ///显示CommandArgument属性的值

        Response.Write(e.CommandArgument.ToString());

    }

}

5.3.6  应用DataKeyField属性

DataList控件的基类BaseDataList提供了与数据源键值相关的DataKeyField和DataKeys属性。其中,DataKeyField属性指定DataList控件的数据源中的键字段。DataKeys属性为一个集合,它保存DataList控件中每一个记录的键值。通过DataKeys属性,可以访问DataList控件中每一行记录的键值。

下面的代码实例获取了DataList控件中的DataKeys属性中的每一行的键值,并显示在名称为lbIDValue的控件中。

protected void dlUser_ItemDataBound(object sender,DataListItemEventArgs e)

{

    if(e.Item.ItemType == ListItemType.Item

        || e.Item.ItemType == ListItemType.AlternatingItem)

    {

        Label lbIDValue = (Label)e.Item.FindControl("lbIDValue");

        if(lbIDValue != null)

        {   ///获取DataKeys属性中的值,并显示

              lbIDValue.Text = dlUser.DataKeys[e.Item.ItemIndex].ToString();

        }

    }

}

下面的实例代码在ButtonKey.aspx页面上声明一个DataList控件和一个SqlDataSource数据源控件,它们的ID属性的值分别为dlUser和myDSUser。其中,myDSUser控件为dlUser的数据源控件,并为该控件提供数据。另外,dlUser控件还定义两个事件:ItemDataBound和ItemCommand,它们的名称分别为dlUser_ItemDataBound(object sender, DataListItem EventArgs e)和dlUser_ItemCommand(object source,DataListCommandEventArgs e)。

<!-- Sample_05_03的ButtonKey.aspx页面 -->

<%@ Page Language="C#" %>

<script runat="server">

///省略了dlUser_ItemDataBound(object sender,DataListItemEventArgs e)和

///dlUser_ItemCommand(object source,DataListCommandEventArgs e)事件的代码

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server"><title>应用DataKeyField属性</title></head>

<body><form id="form1" runat="server">

<asp:DataList ID="dlUser" runat="server" BackColor="White"

    BorderStyle="None" BorderWidth="1px" CellPadding="3" DataKeyField="ID"

    DataSourceID="myDSUser" GridLines="Both" Font-Size="9pt"

    OnItemDataBound="dlUser_ItemDataBound" RepeatDirection="Horizontal"

    OnItemCommand="dlUser_ItemCommand" BorderColor="#CCCCCC">

    <HeaderTemplate>

        <table border="1">

            <tr>

                <td>键值</td>

                <td>用户名称</td>

                <td>电子邮件</td>

                <td>操作</td>

            </tr>

    </HeaderTemplate>

    <ItemTemplate>

            <tr>

                <td><asp:Label ID="lbIDValue" runat="server">

                     </asp:Label></td>

                <td><%# Eval("UserName").ToString() %></td>

                <td><%# Eval("Email").ToString() %></td>

                <td><asp:Button ID="btnShow" runat="server" Text="显示ID"

                  CommandName="show" CommandArgument='<%# Eval("ID") %>'

                  /></td>

            </tr>

    </ItemTemplate>

    <AlternatingItemTemplate>

            <tr>

                <td><asp:Label ID="lbIDValue" runat="server">

                     </asp:Label></td>

                <td><%# Eval("UserName").ToString() %></td>

                <td><%# Eval("Email").ToString() %></td>

                <td><asp:Button ID="btnShow" runat="server" Text="显示ID"

                  CommandName="show" CommandArgument='<%# Eval("ID") %>'

                  /></td>

            </tr>

    </AlternatingItemTemplate>

    <FooterTemplate>

        </table>

    </FooterTemplate>

</asp:DataList>

<asp:SqlDataSource ID="myDSUser" runat="server" ConnectionString="<%$

    ConnectionStrings:WEB2ASPNET2DBConnectionString %>"

    SelectCommand="SELECT [ID], [UserName], [Email], [CreateDate]

        FROM [User]"></asp:SqlDataSource>

</form></body>

</html>

上述代码实例执行之后,ButtonKey.aspx页面如图5.22所示。单击用户名称为“12345”所在行的【显示ID】按钮,ButtonKey.aspx页面将显示该行数据的键值“12”,如图5.23所示。

   

      图5.22  ButtonKey.aspx页面的初始界面                 图5.23  显示指定行的键值

5.3.7  DataList控件的事件

DataList控件提供了与行行为,以及对行的数据进行选择、编辑、更新、删除等操作相关的事件,如表5-18所示。

表5-18                                                       DataList控件的事件

事    件

描    述

ItemCommand

单击控件中的按钮时发生

ItemCreated

控件创建项时发生

ItemDataBound

控件中的项被数据绑定之后发生

EditCommand

单击控件中的【编辑】按钮时发生

CancelCommand

单击控件中的【取消】按钮时发生

UpdateCommand

单击控件中的【更新】按钮时发生

DeleteCommand

单击控件中的【删除】按钮时发生

SelectedIndexChanged

在两次服务器发送之间,当控件中选择了不同的项时发生

单击DataList控件中的按钮(如Button、ImageButton等)时,将触发ItemCommand事件。单击DataList控件中的【编辑】按钮时,将触发EditCommand事件。此时,DataList控件处于编辑状态,它将在【编辑】按钮位置处显示【更新】和【取消】按钮。单击【更新】按钮,控件将用户更新操作的结果提交到数据库;单击【取消】按钮,控件将取消本次编辑操作,然后恢复到非编辑状态。

单击DataList控件中的【删除】按钮时,将触发DeleteCommand事件。在两次服务器发送之间,若DataList控件的选择项发生改变时,将触发SelectedIndexChanged事件。

下面的代码实例在dlClick.aspx页面中定义了DataList控件的Init、Load、ItemCreated、DataBinding、ItemCommand、ItemDataBound、PreRender等事件,并且每一个事件在执行时将显示该事件的名称。如果事件与控件的项(Item)相关,则显示当前项(Item)的索引值。

<!-- Sample_05_03的dlClick.aspx页面 -->

<%@ Page Language="C#" %>

<script runat="server">

protected void dlUser_ItemCreated(object sender,DataListItemEventArgs e)

{   ///显示事件的名称

    Response.Write("第" + (e.Item.ItemIndex + 1).ToString()

        + "正在执行dlUser_ItemCreated()事件……<br />");

}

protected void dlUser_ItemDataBound(object sender,DataListItemEventArgs e)

{   ///显示事件的名称

    Response.Write("第" + (e.Item.ItemIndex + 1).ToString()

        + "正在执行dlUser_ItemDataBound()事件……<br />");

}

protected void dlUser_Init(object sender,EventArgs e)

{   ///显示事件的名称

    Response.Write("dlUser_Init()事件正在执行……<br />");

}

protected void dlUser_Load(object sender,EventArgs e)

{   ///显示事件的名称

    Response.Write("dlUser_Load()事件正在执行……<br />");

}

protected void dlUser_PreRender(object sender,EventArgs e)

{   ///显示事件的名称

    Response.Write("dlUser_PreRender()事件正在执行……<br />");

}

protected void dlUser_DataBinding(object sender,EventArgs e)

{   ///显示事件的名称

    Response.Write("dlUser_DataBinding()事件正在执行……<br />");

}

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server"><title>DataList控件的事件</title></head>

<body><form id="form1" runat="server">

<asp:DataList ID="dlUser" runat="server" BackColor="White"

    BorderStyle="None" BorderWidth="1px" CellPadding="3" DataKeyField="ID"

    DataSourceID="myDSUser" GridLines="Both" Font-Size="9pt"

    OnItemDataBound="dlUser_ItemDataBound" RepeatDirection="Horizontal"

    BorderColor="#CCCCCC" OnItemCreated="dlUser_ItemCreated"

    OnInit="dlUser_Init" OnLoad="dlUser_Load"

    OnPreRender="dlUser_PreRender" OnDataBinding="dlUser_DataBinding">

    <HeaderTemplate>

        用户名称

    </HeaderTemplate>

    <ItemTemplate>

        <%# Eval("UserName").ToString() %>

    </ItemTemplate>

    <AlternatingItemTemplate>

        <%# Eval("UserName").ToString() %>

    </AlternatingItemTemplate>

</asp:DataList>

<asp:SqlDataSource ID="myDSUser" runat="server" ConnectionString="<%$

    ConnectionStrings:WEB2ASPNET2DBConnectionString %>"

    SelectCommand="SELECT [ID], [UserName], [Email], [CreateDate]

        FROM [User]"></asp:SqlDataSource>

</form></body>

</html>

上述代码实例的执行结果如图5.24所示。

图5.24  显示DataList控件的事件执行结果

原文地址:https://www.cnblogs.com/jiangyuxuan/p/843825.html