有没有办法使用“<%= someObject.ClientID%>”在外部JavaScript文件中?

时间:2011-06-30 23:08:53

标签: javascript asp.net ascx clientid

有没有办法使用“<%= someObject.ClientID%>”在外部JavaScript文件中?

如果我使用代码

<%= someObject.ClientID %>

在我的as(c / p)x页面内的脚本标签中,它可以正常工作。在呈现的页面上,ClientID已解析。 但是,如果我输入外部JS文件并添加:

没有。有没有办法做到这一点,还是我坚持将该代码留在as(c / p)x文件中?

附带问题 - 做什么行为&lt;%= ...%&gt;在你的标记文件中叫做?

8 个答案:

答案 0 :(得分:32)

如果您真的想这样做,可以执行以下操作

<%@ Page ContentType="text/javascript" Language="C#" AutoEventWireup="false" %>
<%@ OutputCache Duration="86400" Location="Any" VaryByParam="None" %>

var time = "<%= DateTime.Now.ToString() %>";
alert(time);

然后在您的页面中引用它

<script src="Scripts/file.aspx" type="text/javascript"></script>
  

注意当使用提到的方法时,传递目标页面控制client-id的唯一方法是将客户端id作为字符串存储在公共属性中,然后使用新实例引用它那页

如果唯一使您这样做的是client-id,那么您可以使用以下ASP.NET 4功能

<any-tag ID="myCustomId" runat="server" ClientIDMode="Static" />

您还可以将所有客户端ID放在C#类中,然后使用JSON对其进行序列化并在脚本标记中呈现它,对于版本4之前的ASP.NET可能是明智的方式。

  

注意使用序列化方法有可能更改任何标记ID 而不必担心javascript元素的使用情况,请记住,ASP.NET无法实现这一点4 ClientIDMode

页-代码文件

public partial class About : System.Web.UI.Page
{
    ...

    protected string GetTagIds()
    {
        return new JavaScriptSerializer()
                    .Serialize(new
                     {
                            myButton = Button1.ClientID,
                            myCalendar = Calendar1.ClientID
                     });
    } 

    ...
}

页-ASPX

<script type="text/javascript">
    var IDs = <%= GetTagIds() %>;
</script>

任何地方

<script type="text/javascript">
    IDs.myCalendar.doSomthing...
</script>

还有另一个选项,您可以将所有javascript文件传递给ASP.NET处理程序,但我不推荐它,因为只有一个javascript文件,您使asp.net处理程序忙。

代码块

&lt;%内联代码%&gt;

这是一个内联代码定义,您可以在其中执行代码:

<% Response.Write("Hi"); %>

<% while(i < 0) { %>
      <% 
         Response.Write(i.ToString()); 
         i++;
      %>
<%}%>
  

注意 您必须包含';'在使用C#语言的内联代码时,在每个语句的末尾,您可以使用页面指令语言属性更改内联语言

&lt;%=内联表达式%&gt;

这个等于调用Response.Write你的自己,见:

<%= "Hi" %> equals to <% Response.Write("Hi"); %>
  

注意 您不应包含';'使用内联表达时

&lt;%:编码内联表达式%&gt;

这个等于:

Response.Write(HttpUtility.HtmlEncode("<script type="text/javascript">alert('XSS');</script>"))

出于安全原因使用 - XSS ,任何输入HTML都会输出HTML编码文本,可以安全地在页面中显示用户输入的内容。

  

注意 您不应包含';'使用编码内联表达式时

&lt;%$ expressionPrefix:expressionField%&gt;

这个表达式可以用来绑定ConnectionStrings,Resources和AppSettings中的值

expressionPrefix的可能性是

  • 的AppSettings
  • 的ConnectionStrings
  • 资源

expressionField是您需要的指定expressionPrefix的属性,请参阅:

// AppSettings
<asp:Label ... Text="<%$ AppSettings: version %>" />

// ConnectionStrings
<asp:SqlDataSource ... ConnectionString="<%$ ConnectionStrings:dbConnectionString %>" />

// Resources
<asp:Label ... Text="<%$ Resources: Messages, Welcome %>" />
  

注意 您不应包含';'并且您只能在ASP.Net控件属性

上使用表达式

&lt;%#data-binding expression%&gt;

您可以在具有数据绑定支持的控件内的任何位置使用它,并且通常由Eval和Bind方法使用。

<asp:DropDownList SelectedValue='<%# Bind("CategoryID") %>' 
                  DataSourceID="CategoriesDataSource"
                  DataTextField="CategoryName"
                  DataValueField="CategoryID"
                  runat="Server" />

哪一个Eval或Bind?

使用Bind你有双向绑定设置在ASP.NET控件的指定属性上看到提到的下拉,它使用Bind意味着如果最终用户选择一个值然后提交页面,下拉将没有放松它的选定值。

仅使用Eval显示数据。

<asp:FormView ...>
     <ItemTemplate>
          <a href='Eval("Link")'>Eval("LinkText")</a>
     </ItemTemplate>
</asp:FormView>

&lt;%@ text template directive%&gt;

<%@ Page ...%>
This one is Page Directive

<%@ OutputCache...%>
This one is OutputCache Directive and so on...

答案 1 :(得分:20)

这完全有可能。

在您的表示层(您的.aspx页面)中,创建一个包含您的javascript代码的aspx页面的脚本引用:

<script src="../MyJavaScriptFile.js.aspx" type='text/javascript'></script>

然后,在MyJavaScriptFile.js.aspx中,您可以编写以下内容:

<%@ Page Language="C#" AutoEventWireup="false"  ContentType="text/javascript" %>

    <% 
        CustomPersonObject cpt = new CustomPersonObject();
        cpt.firstname = "John";
        cpt.lastname  = "Smith";
    %>

// Start Javascript
var personFirstName = '<% HttpContext.Current.Response.Write(cpt.name);%>';
var personLastName = '<% HttpContext.Current.Response.Write(cpt.lastname);%>'

我经常使用的一种技术是将我需要在我的javascript文件中评估的值作为初始脚本引用中的url参数传递:

 <script src="../MyJavaScriptFile.js.aspx?username=<% somevalue %>" 
       type='text/javascript'></script>

然后,在MyJavaScriptFile.js.aspx中,我可以用

引用该值
<% Request.QueryString["username"] %>

这不是做事的“最佳实践”方式,但它可以通过我的穴居人大脑可以理解的方式完成工作,而无需借助花哨的解决方法和额外的代码。

答案 2 :(得分:3)

我喜欢在我的网页上嵌入一行javascript。

<script type="text/javascript">
   Application.init({variable1: "value1", variable2: "value2"...});
</script>

在您的页面上渲染大量的javascript是不好的做法,但通常需要将初始化值从服务器传递给您的javascript。这允许您在没有大量不必要的代码的情况下执行此操作,并且不会使用回调函数污染全局命名空间。我通常用一些项目特定的全局包装器替换Application

答案 3 :(得分:3)

这会增加一些HTML,但它有效;将每个服务器控件包装在div中......

<div id="myContainer">
    <asp:HiddenField ID="hdMyControl" runat="server" /></div>

后面的代码中设置HiddenField的值
hdMyControl.Value = "something";

然后在外部JS文件中,您可以获得服务器控件的值

$(document).ready(function () {
    var myValue= $('#myContainer input[type=hidden]').val();

我不确定这是否重要,但我正在使用RegisterClientScriptBlock

通过代码隐藏向页面添加脚本引用

答案 4 :(得分:1)

您可以在外部文件中创建一个空回调函数:

var MyCallback = function () { };

然后在asp / cx中做类似的事情:

MyCallback = function () {return "<%= someObject.ClientID %>";}

然后,回到你的外部文件中:

var myClientID = MyCallback();

答案 5 :(得分:1)

不,它不会那样工作,因为javascript文件作为一个单独的文件被独立传输,并且在解决方法时不会被ASP.NET解析,而你的aspx文件正在被解析和.NET引擎正在用实际值替换标签。

现在,当你的对象调用那些JS函数时,他们可以做的是将对自己的引用传递给函数,或者甚至用你自己的密钥传入某种类型的字典列表中的控件是什么和指定的名称。 / p>

要考虑的一件事 - 如果你要创建一个独立于ASPX页面的JS文件,那么JS文件绝对不应该假设知道任何关于特定控件的信息。调用它的aspx文件 - 因为稍后其他人可能会决定,“哦,这是一个很好的JS文件,我也会加入它”并且它不会对它们起作用,因为它们的对象不会与你的对象相匹配。因此,您应该遵循的模式必须更通用 - 这就是为什么您要传递引用或标识符列表。

答案 6 :(得分:1)

服务器标记<%= %>用于输入在服务器上处理的代码。

你不能在外部js文件中使用<%= someObject.ClientID %>,因为服务器标签是asp.net的东西而js不知道这是什么。

如果使用ASP.NET 4,则可以在控件的属性中设置客户端ID,使其可预测。

如果您不使用ASP.NET 4,则可以将此客户端ID放在隐藏字段或内联js变量中。

答案 7 :(得分:-5)

在脚本源文件中使用标准前缀标识符:

document.getElementById("ctl00_ContentDetail_textboxelename").value = "";
document.getElementById("ctl00_ContentDetail_radioORcheckboxelename").checked = false;
document.getElementById("ctl00_ContentDetail_elename").style.visibility = "hidden";
var javaele = document.getElementById("ctl00_ContentDetail_elename");
var boolIsChecked = document.getElementById("ctl00_ContentDetail_radioORcheckboxelename").checked;