我需要通过javascript获取自定义控件中的最新文本集。当我试图从服务器控件获取所选文本时,它总是返回默认文本&不是修改过的文字。如何保留servercontrol中javascript设置的最新值?以下是供您参考的完整代码..
ServerControl1.cs
[assembly: WebResource("ServerControl1.Scripts.JScript1.js", "text/javascript")]
namespace ServerControl1
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")]
public class ServerControl1 : WebControl
{
public List<string> ListItems
{
get
{
return ViewState["items"] as List<string>;
}
set
{
ViewState["items"] = value;
}
}
public string Text
{
get
{
return (FindControl("middleDiv").FindControl("anchorID") as HtmlAnchor).InnerText;
}
set
{
((FindControl("middleDiv").FindControl("anchorID") as HtmlAnchor)).InnerText = value;
}
}
protected override void CreateChildControls()
{
base.CreateChildControls();
HtmlGenericControl selectedTextContainer = new HtmlGenericControl("div");
selectedTextContainer.ClientIDMode = System.Web.UI.ClientIDMode.Static;
selectedTextContainer.ID = "middleDiv";
HtmlAnchor selectedTextAnchor = new HtmlAnchor();
selectedTextAnchor.ClientIDMode = System.Web.UI.ClientIDMode.Static;
selectedTextAnchor.ID = "anchorID";
selectedTextAnchor.HRef = "";
selectedTextContainer.Controls.Add(selectedTextAnchor);
HtmlGenericControl unList = new HtmlGenericControl("ul");
foreach (string item in ListItems)
{
HtmlGenericControl li = new HtmlGenericControl("li");
HtmlAnchor anchor = new HtmlAnchor();
anchor.HRef = "";
anchor.Attributes.Add("onclick", "updateData()");
anchor.InnerText = item;
li.Controls.Add(anchor);
unList.Controls.Add(li);
}
selectedTextContainer.Controls.Add(unList);
Controls.Add(selectedTextContainer);
ChildControlsCreated = true;
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
string resourceName = "ServerControl1.Scripts.JScript1.js";
ClientScriptManager cs = this.Page.ClientScript;
cs.RegisterClientScriptResource(typeof(ServerControl1), resourceName);
}
}
}
JScript1.js
function updateData() {
var evt = window.event || arguments.callee.caller.arguments[0];
var target = evt.target || evt.srcElement;
var anchor = document.getElementById("anchorID");
anchor.innerText = target.innerText;
return false;
}
TestPage Codebehind
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<string> items = GetDataSource();
ServerControl1.ListItems = items;
ServerControl1.Text = "Select ..";
}
}
protected void ClientButton_Click(object sender, EventArgs e)
{
string selectedText = ServerControl1.Text;
}
答案 0 :(得分:2)
除非您将更改发布给他,否则服务器将无法更改客户端。您的HtmlAnchors将以HTML格式呈现为<a>
控件,这些类型的控件不会向服务器发送任何内容。
您需要一个<input>
控件来将更改输入到服务器中(这就是为什么它们之后被称为输入控件)。我建议<input type=hidden>
保持anchor.innerText
的值并保持其状态。
您的Javascript函数需要进行修改,以便更新anchor.innerText
并更新隐藏的输入值。这样,当页面回发到服务器时,您可以从隐藏字段中检索更新的和客户端修改的值。
首先,您需要将selectedTextAnchor
和要插入的hiddenField
定义为私有字段。这是因为您需要在CreateChildControls方法以及yout Text属性的getter和setter中访问它们。部分设计器类在很大程度上定义了您希望在代码隐藏中可用的控件。
<强> ServerControl.cs 强>
private HtmlAnchor selectedTextAnchor;
private HtmlInputHidden hiddenField;
在CreateChildControls方法中,您需要插入隐藏字段。
您会注意到我删除了ClientIDMode.Static的使用。使用该模式会使您的客户端控件具有相同的固定ID,并且当您在页面中有多个ServerControl副本时,Javascript可能会混淆,从而失去自定义控件的可重用目的。
相反,您需要为您的Javascript函数提供需要修改的控件的ClientID。 此处的关键是,在尝试获取其ClientID之前,需要将控件附加到Control的层次结构。
只要你做this.Controls.Add(dummyControl)
,你就会让dummyControl成为Page的一部分,它的dummyControl.ClientID
会突然改变,以反映你将它附加到的页面的层次结构
我更改了控件附加到Control集合的顺序,因此我们可以在构建onclick属性时获取其ClientID并传递参数,以便您的Javascript函数知道要影响哪个锚点和hiddenField。
<强> ServerControl.cs 强>
protected override void CreateChildControls()
{
base.CreateChildControls();
// Instantiate the hidden input field to include
hiddenField = new HtmlInputHidden();
hiddenField.ID = "ANCHORSTATE";
// Insert the hiddenfield into the Control's Collection hierarchy
// to ensure that hiddenField.ClientID contains all parent's NamingContainers
Controls.Add(hiddenField);
HtmlGenericControl selectedTextContainer = new HtmlGenericControl("div");
// REMOVED: selectedTextContainer.ClientIDMode = System.Web.UI.ClientIDMode.Static;
selectedTextContainer.ID = "middleDiv";
selectedTextAnchor = new HtmlAnchor();
// REMOVED: selectedTextAnchor.ClientIDMode = System.Web.UI.ClientIDMode.Static;
selectedTextAnchor.ID = "anchorID";
selectedTextAnchor.HRef = "";
selectedTextContainer.Controls.Add(selectedTextAnchor);
// Insert the selectedTextContainer (and its already attached selectedTextAnchor child)
// into the Control's Collection hierarchy
// to ensure that selectedTextAnchor.ClientID contains all parent's NamingContainers
Controls.Add(selectedTextContainer);
HtmlGenericControl unList = new HtmlGenericControl("ul");
foreach (string item in ListItems)
{
HtmlGenericControl li = new HtmlGenericControl("li");
HtmlAnchor anchor = new HtmlAnchor();
anchor.HRef = "";
// The updateData function is provided with parameters that will help
// to know who's triggering and to find the anchor and the hidden field.
// ClientID's are now all set and resolved at this point.
anchor.Attributes.Add("onclick", "updateData(this, '" + selectedTextAnchor.ClientID + "', '" + hiddenField.ClientID + "')");
anchor.InnerText = item;
li.Controls.Add(anchor);
unList.Controls.Add(li);
}
selectedTextContainer.Controls.Add(unList);
}
请注意在updateData函数中使用关键字this
,它将帮助我们获取触发操作的对象。另请注意,两个Id都作为字符串传递(带单引号)
需要修改Javascript函数,以便更新锚点和隐藏的输入字段。
JScript1.js
function updateData(sender, anchorId, hidFieldId) {
// Update the anchor
var anchor = document.getElementById(anchorId);
anchor.innerText = sender.innerText;
// Update the hidden Input Field
var hidField = document.getElementById(hidFieldId);
hidField.value = sender.innerText;
return false;
}
最后要做的是更改设置和获取Text属性的方式。
当您获取该属性时,您需要检查它是否为回发,如果是,则您要检查来自浏览器的所有信息中是否有您的HiddenInputField。您可以在Request对象中获取来自客户端的所有信息,更具体地说,可以在Request.Form中获取。
页面上所有已启用的输入控件都将成为Request.Form集合的一部分,您可以使用Request.Form[anyInputControl.UniqueID]
获取其值。请注意,用于此对象的密钥是UniqueID,而不是ClientID。
从隐藏的输入中获取客户端修改后的值后,将其值分配给selectedTextAnchor
,否则它将返回原始的“选择...”文本。
当您设置该属性时,您只需将其分配给selectedTextAnchor
。
在 GET和SET 中,您需要拨打EnsureChildControls()
,这实际上会调用CreateChildControls()
以确保您的selectedTextAnchor
和{{1}在尝试获取某些属性之前,会实例化控件。与在Composite Controls中完成的方式非常相似。
<强> ServerControl.cs 强>
hiddenField
这样您就可以拥有一个控件来识别客户端所做的更改。请记住,除非您发现他,否则服务器不会知道客户端的任何变化。
另一种方法是每次通过ajax请求单击链接时都会注意到服务器,但这需要一个全新的不同代码。
祝你好运!