我有一个中继器(用于内容帖子),其中包含一个更新面板,该面板又包含另一个中继器作为(评论的子级)。
我想要实现的是让用户评论/喜欢帖子。这些值使用 JavaScript/JQuery 进行验证,并使用 PageMethods 发送到服务器。我设法让 UpdatePanel 从 JavaScript 刷新。我面临的问题是我需要以某种方式找到 Posts RepeaterItem 以便我可以创建 Comments Repeater 的实例,以便将其重新绑定到数据源,这将使用户在输入后出现评论。
我现在尝试在线搜索几天,但似乎没有人使用与 JavaScript 和更新面板等混合的嵌套中继器来解决这个问题。我不介意整页回发,我不介意改变我的页面结构如果必要的。我唯一想要的是,当此过程发生时,用户会留在页面上的同一位置,我担心通过完整的页面刷新,用户将被导航回页面顶部。JavaScript 是立即获得反馈的正确方法。然而,我对 ASP 和 C# 中的 JavaScript 还是陌生的,所以这被证明是一个挑战。
结构
Repeater (Posts)
|
---- Update Panel (for refreshing childeren from JavaScript)
|
---- Repeater (Comments)
ASP 代码
<asp:Repeater ID="rptActivityStream" runat="server" OnItemDataBound="rptActivityStream_ItemDataBound">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<asp:HiddenField ID="hfActivityStreamID" value='<%#Eval("ActivityStreamID") %>' runat="server" />
<table style="width:100%;">
<tr>
<td style="width:100%;">
<div class="card">
<div class="cardheader">
<table style="width:100%;">
<tr>
<td style="width:80%; text-align:left;">
<div style="display:inline-block">
<img src='<%#Eval("Avatar") %>' class="listmenuavatar" />
<%#Eval("FullName") %>
</div>
<div style="display:inline-block">
<%#Eval("ActivityStreamTitleHTML") %>
</div>
</td>
<td style="width:20%; text-align:right;">
<div style="display:inline-block">
<%#Eval("TimeAgo") %>
</div>
</td>
</tr>
</table>
</div>
<div class="cardbody">
<%#Eval("ActivityStreamContentHTML") %>
</div>
<div id="cardfooter" class="cardfooter">
<asp:UpdatePanel ID="UpdPnlComments" runat="server" UpdateMode="Conditional" OnLoad="UpdPnlComments_Load">
<ContentTemplate>
<asp:Repeater ID="rptSocialData" runat="server">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<button id="btnLike" type="button" class="btn btn-default btn-sm">
<input id="hdnASID" type="hidden" runat="server" value='<%#Eval("ActivityStreamID") %>'/>
<span class="glyphicon glyphicon-thumbs-up"></span> Like
</button>
<button id="btnComment" type="button" class="btn btn-default btn-sm">
<input id="hdnASID2" type="hidden" runat="server" value='<%#Eval("ActivityStreamID") %>'/>
<span class="glyphicon glyphicon-comment"></span> Comment
</button>
<%#Eval("LikeCount") %>
<%#Eval("CommentCount") %>
</ItemTemplate>
<FooterTemplate></FooterTemplate>
</asp:Repeater>
<div class="commentsDiv" style="display:none; margin-top:10px;">
<div style="display:inline-block; vertical-align: top;">
<img src='<%#Eval("Avatar") %>' class="listmenuavatar" />
</div>
<div class="commentBoxDiv form-group has-feedback" style="display:inline-block; padding-left: 10px; padding-right: 10px; width:30%;">
<asp:TextBox ID="txtComment" CssClass="commentBox form-control" runat="server" TextMode="MultiLine" Font-Size="8pt"></asp:TextBox>
</div>
<div style="display:inline-block; vertical-align: top;">
<button id="btnSendComment" type="button" class="post-Comment btn btn-primary btn-sm" data-id='<%#Eval("ActivityStreamID") %>'>
<span class="glyphicon glyphicon-comment"></span> Send
</button>
</div>
<div style="display:block; padding-top:20px;">
<asp:Repeater ID="rptComments" runat="server">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<table style="width:100%; padding-left:5px; padding-right:5px;">
<tr>
<td style="width:50%; text-align:left; vertical-align:top; padding-left:10px; padding-top: 15px;">
<div style="text-align:center; display:table;">
<div style="float:left;">
<asp:Image ID="Image1" runat="server" CssClass="commentavatar" ImageUrl='<%#Eval("AuthorAvatar") %>'/>
</div>
<div style="vertical-align: middle; padding-left: 10px; display: table-cell;">
<%#Eval("Author") %>
</div>
</div>
</td>
<td style="width:50%; text-align:right; vertical-align:middle; padding-right:10px;">
<%#Eval("TimeAgo") %>
</td>
</tr>
<tr>
<td style="width:100%; text-align:left;" colspan="2">
</td>
</tr>
<tr>
<td style="width:100%; text-align:left; padding-left:10px;padding-right:10px;" colspan="2">
<div style="border-bottom: solid; border-width: 1px; border-color: #dddddd; padding-bottom: 15px;">
<%#Eval("Comment") %>
</div>
</td>
</tr>
</table>
</ItemTemplate>
<FooterTemplate></FooterTemplate>
</asp:Repeater>
</div>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
</td>
</tr>
</table>
</ItemTemplate>
<FooterTemplate></FooterTemplate>
</asp:Repeater>
JavaScript
$(document).ready(
function ()
{
$('[id*=btnLike]').click(function (event) {
debugger;
event.preventDefault(); //preventing button's default behavior
var ActivityStreamID = $(this).find("input[type=hidden]").val();
var UserID = document.getElementById('<%= hfUserID.ClientID %>').value;
var element = $(this).parent().parent().parent();
var result = PageMethods.LikeActivityStream(ActivityStreamID, UserID, onPostLikeSuccess, onPostLikeFailure);
UpdateUpdPanel(element);
});
$('[id*=btnComment]').click(function (event) {
debugger;
event.preventDefault(); //preventing button's default behavior
var ASID2 = $(this).find("input[type=hidden]").val();
var element = $(this).parent().parent().parent(); //get the update panel
var commentdiv = element.find(".commentsDiv"); // find commentsDiv in the update panel
commentdiv.css("display", "block"); // set the text to red as a test.
});
function UpdateUpdPanel(element) {
__doPostBack(element, '');
}
function onPostLikeSuccess(result) {
//refresh repeater / update panel ?
}
function onPostLikeFailure(result) {
likeerror();
}
function likeerror() {
swal({
title: 'Uh-Oh!',
text: 'Something went wrong while liking this post! Please try again and if the problem persists, please contact the system administrator.',
type: 'error'
});
}
});
$(document).on("click", ".post-Comment", function () {
var ActivityStreamID = $(this).data('id');
var UserID = document.getElementById('<%= hfUserID.ClientID %>').value;
var element = $(this).parent().parent();
var element2 = $(this).parent().parent().parent();
var commentboxdiv = element.find(".commentBoxDiv");
var commentbox = commentboxdiv.find(".commentBox");
var comment = commentbox.val();
if (comment != "") {
commentboxdiv.removeClass('has-error');
var result = PageMethods.CreateActivityStreamComment(ActivityStreamID, comment, UserID, onPostCommentSuccess, onPostCommentFailure, element2);
}
else {
commentboxdiv.addClass('has-error');
}
function onPostCommentSuccess(result, context) {
//refresh repeater / update panel?
debugger;
var element = context;
UpdateUpdPanel(element);
}
function UpdateUpdPanel(element) {
debugger;
__doPostBack(element, '');
}
function onPostCommentFailure(result) {
commenterror();
}
function commenterror() {
swal({
title: 'Whaaaa?!',
text: 'Something went wrong while posting your comment! Please try again and if the problem persists, please contact the system administrator.',
type: 'error'
});
}
});
C# 代码(在更新面板中刷新评论转发器)
protected void UpdPnlComments_Load(object sender, EventArgs e)
{
// Missing code here to create an instance of the rptSocialData and rptComments repeaters
// so that they can be data bound
// hfActivityStream will also have to be accessed
DatabaseHelper dh = new DatabaseHelper();
DataTable dtSocialData = new DataTable();
dtSocialData = dh.GetActivityStreamSocialData(hfActivityStreamID.Value);
rptSocialData.DataSource = dtSocialData;
rptSocialData.DataBind();
DataTable dtComments = new DataTable();
dtComments = dh.GetActivityStreamComments_All(hfActivityStreamID.Value);
rptComments.DataSource = dtComments;
rptComments.DataBind();
}
我如何在 OnDataBound 方法中完全实现服务器端的示例
protected void rptActivityStream_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
Repeater rptSocialData = (Repeater)e.Item.FindControl("rptSocialData");
Repeater rptComments = (Repeater)e.Item.FindControl("rptComments");
HiddenField hfActivityStreamID = (HiddenField)e.Item.FindControl("hfActivityStreamID");
DatabaseHelper dh = new DatabaseHelper();
DataTable dtSocialData = new DataTable();
dtSocialData = dh.GetActivityStreamSocialData(hfActivityStreamID.Value);
rptSocialData.DataSource = dtSocialData;
rptSocialData.DataBind();
DataTable dtComments = new DataTable();
dtComments = dh.GetActivityStreamComments_All(hfActivityStreamID.Value);
rptComments.DataSource = dtComments;
rptComments.DataBind();
}
}