如何为ASP.NET用户控件创建客户端API?

时间:2011-06-23 15:18:40

标签: javascript .net user-controls

例如:我有一个用户控件,我们称之为“MyControl1”,我想创建“Show()”和“Hide()”javascript函数,这些函数可以从父页面上的javascript调用 - 类似于“ MyControl1.Show();“

显然页面上可能有多个控件,所以如果您在页面上删除了2个控件:

   <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(无论是否在用户控件中),但如果你在该页面上有2个这样的控件不起作用,那么你如何创建javascript使得父页面可以区分它想要调用的用户控件功能吗?

3 个答案:

答案 0 :(得分:2)

你想做的事情非常简单。 asp.net控件是一种将纯html包装到页面控件中的庞大方法。为了能够在控件上调用javascript事件,您必须知道向页面呈现控件的结果的ID。

注意:所有.net控件都有一个名为.ClientID的成员,这表示运行时将生成的内容作为设计用于封装/呈现的HTML的ID。

为了在呈现页面时获取控件的ID,您需要执行以下操作:

var dotNetHtmlClientID = '<%= txtMessage.ClientID %>';
$('#' + dotNetHtmlClientID).bind('onclick', function(){

    //dostuff

});

第一行是c#内联代码,用于从运行时获取ClientID。

更新 **

如果你想从它所在的页面获取用户控件的clientID,你需要这样做:

//点网页服务器端

protected string controlClientId;

void Page_Load(object sender, Eventargs e)
{

     controlClientId = Page.FindControl("MyControlThatImBindingEventToDotNetId").ClientID;

}

//在页面客户端

var dotNetHtmlClientID = '<%= controlClientId %>';
$('#' + dotNetHtmlClientID).bind('onclick', function(){

    //dostuff

});

答案 1 :(得分:1)

解决此问题的一种方法是在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]'

答案 2 :(得分:1)

我的解决方案涉及在用户控件中添加包装器div,然后使用jQuery扩展它 - 添加您希望的任何客户端方法和属性。诀窍是将包装器div的ID设置为与使用类似id='<%= this.ID %>'的用户控件相同。

用户控件本身并不实际呈现任何内容(仅内容),因此div只会为您提供一个带有ID的对象,您可以在包含的页面上引用它(因为您知道用户控件的ID)。并且您的属性/方法扩展了div,所有内容都整齐地限定(全局命名空间中没有任何内容),您只需使用带有标准$get('myUcWhatever')的用户控件ID获取对象引用 - 您就可以了去。

如果您需要更多详细信息,我可以在我的博客上发布完整的解释和演示解决方案: http://programmerramblings.blogspot.com/2011/07/clientside-api-for-aspnet-user-controls.html

相关问题