如何为ASP.NET用户控件创建客户端API
How do you create a client-side API for an ASP.NET User Control?
例如:我有一个用户控件,让我们称之为"MyControl1",我想创建"Show()"answers"Hide()"javascript函数,这些函数可以从父页上的javascript调用,比如"MyControl1.Show();"
很明显,页面上可能有多个控件,所以如果您在页面上删除了两个控件:
<MyTag:MyControl ID="MyControl1" runat="server" />
<MyTag:MyControl ID="MyControl2" runat="server" />
如果能做这样的事情就太好了:
function ParentPageJavascriptFunction(){
MyControl1.Show();
MyControl2.Hide();
}
我该怎么做?我找到的每一篇文章都是关于如何在用户控件中挂接事件的,我只希望父页面能够在它认为合适的时候调用某些函数,或者也许有一种方法可以使用事件来做我想做的事情,但我只是不理解
编辑:这似乎没有得到正确的理解,这个怎么样。。。
这就是我假设的控制:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyControl.ascx.cs" Inherits="controls_MyControl" %>
<script type="text/javascript">
function Display(msg) {
var Label1ClientID = '<%= Label1.ClientID %>';
document.getElementById(Label1ClientID)... (display the message)
}
</script>
<asp:Label ID="Label1" runat="server"> </asp:Label>
现在,"父"页注册控件如下:
<%@ Register Src="~/controls/MyControl.ascx" TagName="MyControl" TagPrefix="MyTag" %>
在身体里它有这个:
<asp:Button ID="MyButton1" runat="server" Text="Display" OnClientClick="javascript:MyControl1.Display('hello'); return false;" />
<MyTag:MyControl Id="MyControl1" runat="server">
</MyTag:MyControl>
显然,唯一的问题是,这不起作用,但这正是我想要解决的问题。你是如何做到这一点的?我希望能够允许用户控件嵌套在其中的页面(父页面)能够调用该用户控件的Display函数。我意识到,你可以只调用Display,因为它只是js(无论它是否在用户控件中),但如果你在该页面上有两个这样的控件,那么你如何创建javascript,使父页面能够区分它想要调用哪个用户控件函数呢?
您尝试做的事情非常简单。asp.net控件是一种将纯html封装到页面控件中的庞大方法。为了能够在控件上调用javascript事件,您必须知道控件呈现到页面的结果的ID。
注意:所有.net控件都有一个名为.ClientID的成员,它表示运行时将生成的内容,作为它设计用于封装/呈现的HTML的ID。
为了在页面上显示控件的ID,您需要执行以下操作:
var dotNetHtmlClientID = '<%= txtMessage.ClientID %>';
$('#' + dotNetHtmlClientID).bind('onclick', function(){
//dostuff
});
第一行是c#内联代码,用于从运行时获取ClientID。
更新**
如果你想从用户控件所在的页面上获得它的客户端ID,你需要这样做:
//在点网页服务器端
protected string controlClientId;
void Page_Load(object sender, Eventargs e)
{
controlClientId = Page.FindControl("MyControlThatImBindingEventToDotNetId").ClientID;
}
//在页面客户端
var dotNetHtmlClientID = '<%= controlClientId %>';
$('#' + dotNetHtmlClientID).bind('onclick', function(){
//dostuff
});
解决这个问题的一种方法是用javascript创建一个模块。简而言之,这意味着您可能拥有xyzClientApi.js
,它包含一些增强页面功能的函数集。
在该文件中,您将创建一个对象,该对象引用了您对脚本功能感兴趣的控件。在javascript中,您可以在函数中嵌套变量或对象,以有效地命名它们的名称空间(这将减少javascript与其他可能使用的javascript之间的冲突)。
此函数将为您的客户端api创建一个作用域:
// this is the variable that you'll reference from your view markup
// the style shown here is a self executing anonymous function.
// sounds scarier than it is! don't be afraid.
var xyzClientApi = (function($) {
// this is the object that will be assigned to xyzClientApi.
// the {} in this line is just an object initializer
// you can put things inside of it using this syntax: <name>:<value>
var model = {};
// you can use an init() function to accept parameters
// when you initialize the api.
// i.e. xyzClientApi.init({myUserControl:'#myUserControl1', myButton:'#myButton1'});
model.init = function(params) {
// add properties and functions to your model
// based on parameters in here
model.myUserControl = {
display: function(text) {
$(params.myUserControl).val(text);
}
};
// assign a click handler to your button!
$(params.myButton).click(function(){
model.myUserControl.display('hello!');
});
};
// remember to return model!
return model;
// by passing jQuery here, the '$' parameter
// is guaranteed to be jQuery when you use it
// this is to play nice with other js libraries
// that might also use '$' at the global scope.
})(jQuery);
然后,你就可以在你的标记中使用这个:
<script type="text/javascript" src="xyzClientApi.js"></script>
<script type="text/javascript">
// standard jQuery DOM ready function
$().ready(function(){
// call the init from above
// this is using the object initializer syntax in javascript
// it's just a nice way of grouping your parameters
// each property of the object is declared, followed by a colon,
// which is followed by a value. this value can be any valid javascript
// object, like a string, value, or some other object.
// in this case, we're passing the known control IDs in.
xyzClientApi.init({
myUserControl: '<%= MyUserControlClientID %>',
myButton: '<%= MyButtonControlClientID %>'
});
});
</script>
如果您不知道控件的ID,或者无法合理地确定它是什么,请尝试将其包装在div或其他html元素中:
<div id="MyControlIsInhere">...your control...</div>
然后你可以使用这样的选择器:
'#MyControlIsInHere input[type=button]'
我的解决方案包括在用户控件中添加一个包装器div,然后使用jQuery对其进行扩展-添加您想要的任何客户端方法和属性。诀窍是将包装器div的ID设置为与用户控件的ID相同,使用id='<%= this.ID %>'
。
用户控件本身实际上并没有呈现任何内容(只有内容),因此div只是为您提供一个对象,该对象的ID可以在包含页面上引用(因为您知道用户控件的ID)。通过在div之外扩展属性/方法,所有内容都有了清晰的范围(全局命名空间中没有任何内容),您可以简单地使用标准$get('myUcWhatever')
使用用户控件的ID获取对象引用,这样就可以开始了。
如果你想了解更多细节,我在博客上发布了完整的解释和演示解决方案:http://programmerramblings.blogspot.com/2011/07/clientside-api-for-aspnet-user-controls.html
- 创建一个方法,通过一个窗口进行迭代并获取Titanium中的所有控件
- 在angularjs中创建自定义控件的推荐方法
- 创建服务器控件.创建问题
- 如何在asp.net中获取动态创建的文本框web控件的值
- 如何在reactjs中创建仅输入控件
- 在Javascript中创建自定义的可重用控件(Kendo UI)
- 动态创建控件时如何使用.data()
- 在JavaScript和HTML中创建intellisense类型控件
- C#WebBrowser控件-使用DOM创建和修改javascript变量,然后使用Applet读取它
- 为多个操作创建ASCX控件
- FindControl无法使用动态创建的控件
- 将动态创建的ASP.NET控件传递给Javascript
- 是否可以在 asp.net 中使用 JavaScript 创建服务器端列表框控件
- Javascript 循环未正确创建 jquery 控件
- 如何在客户端函数行中创建的 RadGrid 的命令项模板中查找控件
- 为动态控件创建 JavaScript
- asp:LinkButton通过文字控件创建,不会在后面触发代码
- 如何为ASP.NET用户控件创建客户端API
- SAPUI5 如何通过扩展现有控件创建自定义控件
- 如何使用键盘控件创建切换按钮