ASP.NET 4.0配置文件中的ClientIDMode属性详解

时光流逝,我们心爱的ASP.NET也步入了4.0的时代,微软在ASP.NET 4.0中对很多特性做了修改。比如我将要讨论的控件ID机制就是其中之一。

在ASP.NET 4.0之前我们总是要为控件的ClientID头疼,比如明明一个叫lblName的Label放在一个叫做grd的GridView里面后,在页面上改Label的ID就变成了诸如grd_clt02_lblName的一长串字符串,如果我们在前台想在使用JS的时候找到该Label,我们不得不用到C#脚本来获得该Label在前台的确切ID,诸如:

< type="text/ ">
  var lblName = document.getElementById("<%=lblName.ClientID %>");
</ >

在ASP.NET 4.0中的每个控件上都多了一个叫做ClientIDMode的属性,这就是解决上面获取控件ID难的解决方案。这个属性有四个可选值,根据所选值的不同它可以控制页面上生成控件的ID格式。

下面就让我们来了解下ClientIDMode属性的四个值:

1,AutoID:

当控件的ClientIDMode选中为AutoID时,该控件的ClientID 值是通过串联每个祖先容器控件(诸如GridView、ListView、LoginView等就是容器性控件)的ID和父容器控件的ID和其本身的ID 值生成的,当然如果该控件没有在任何容器控件中其ClientID 值就是其本身的ID值,不会做任何更改。 另外如果该控件所在的父容器控件或祖先容器控件有些是显示多个数据行的容器控件(例如GridView、ListView就是显示多数据行的容器控件),那么还将在这些容器控件的ID值的后面会插入一个递增的行号格式。 各部分之间以下划线字符 (_) 分隔。 可见在 ASP.NET 4 之前的版本中使用的就是AutoID方案来生成控件的ClientID 值。

比如下面这个GridView里面就有一个名叫Label1的ID,我们将Label1的ClientIDMode设置为了AutoID:

<asp:GridView ID="grd_Account" runat="server" AllowPaging="True"
  AutoGenerateColumns="False"
  DataKeyNames="Account Number" DataSourceID="sds_account" Height="63px"
  Width="676px" PageSize="5" ClientIDMode="AutoID" >
  <Columns>
    <asp:TemplateField HeaderText="Account Number" Sort ="Account Number">
      <ItemTemplate>
        <asp:Label ID="Label1" runat="server"
          Text='<%# Bind("[Account Number]") %>' ClientIDMode="AutoID"></asp:Label>
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>

该GridView生成的客户端HTML代码就是:

<table cellspacing="0" rules="all" border="1" id="grd_Account" style="height:63px;width:676px;border-collapse:collapse;">
  <tr>
    <th scope="col">Account Number</th>
  </tr>
    <tr>
  <td>
      <span id="grd_Account_ctl02_Label1">1060</span>
    </td>
  </tr>
    <tr>
  <td>
      <span id="grd_Account_ctl03_Label1">1200</span>
    </td>
  </tr>
    <tr>
  <td>
      <span id="grd_Account_ctl04_Label1">1510</span>
    </td>
  </tr>
</table>

可以看到GirdView里面的Label形成了诸如grd_Account_ctl02_Label1格式的ClientID,而这正是:父容器ID(grd_Account)+"_"+行号格式(ctl02)+"_"+控件自身ID(ClientID)这种格式生成的。

2,Static:

当控件的ClientIDMode选中为Static时,该控件的ClientID 值就是其本身设置的 ID 属性值,其ClientID值不会受到父容器控件的影响。

比如我们把上面的代码稍作修改,将Label1的ClientIDMode属性改为Static:

<asp:GridView ID="grd_Account" runat="server" AllowPaging="True"
  AutoGenerateColumns="False"
  DataKeyNames="Account Number" DataSourceID="sds_account" Height="63px"
  Width="676px" PageSize="5" >
  <Columns>
    <asp:TemplateField HeaderText="Account Number" Sort ="Account Number">
      <ItemTemplate>
        <asp:Label ID="Label1" runat="server" Text='<%# Bind("[Account Number]") %>' ClientIDMode="Static"></asp:Label>
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>

运行后查看得到的HTML代码:

<table cellspacing="0" rules="all" border="1" id="grd_Account" style="height:63px;width:676px;border-collapse:collapse;">
  <tr>
    <th scope="col">Account Number</th>
  </tr><tr>
    <td>
      <span id="Label1">1060</span>
    </td>
  </tr><tr>
    <td>
      <span id="Label1">1200</span>
    </td>
  </tr><tr>
    <td>
      <span id="Label1">1510</span>
    </td>
  </tr>
</table>

看到了吗,GridView里每行的Label1的ClientID都以自身ID的值出现了,不会受到父级容器控件的ID影响,这样在前台使用JS时我们就能通控件本身的ID值找到我们想要的控件了。

此外使用Static后势必页面中会出现很多同名的控件ID,只要这些同名ID的控件处于页面的不同层次(比如某一容器控件的内部和外部就是不同层次)上那么就不会出现问题,但是如果页面同一层次上有多个同ID的控件,那么页面就会报错。

3,Inherit:

这个属性其实没什么好说的,如果控件的ClientIDMode选中为Inherit,那么表示该控件的ClientIDMode会使用父级容器控件的ClientIDMode值,如果父级容器控件的ClientIDMode也为Inherit,那么会使用更上层容器控件的ClientIDMode值,直到回溯到页面的ClientIDMode值为止,页面的ClientIDMode值默认为Predictable ,你可以在页面上的<%@ Page%>指令中对该值做更改。此外Inherit也是ASP.NET 4.0中所有控件的ClientIDMode属性的默认值。

4,Predictable:

首先我先说明下之所以最后写Predictable,是因为我发现控件的ClientIDMode为Predictable时生成ClientID的机制会非常复杂,要分好几个部分分别进行讨论,其中还有特殊情况,所以我在这里只能说尽量将我发现的Predictable生成ClientID的机制阐述清楚。

当控件的ClientIDMode选中为Predictable时,该控件的ClientID 值是通过串联父容器控件(诸如GridView、ListView、LoginView等就是容器性控件)的 ClientID 值生成的。另外如果该控件是在显示多个数据行的父容器控件或祖先容器控件中(例如GridView、ListView就是显示多数据行的容器控件),则还会在该控件ClientID 值的末尾添加 ClientIDRowSuffix 属性中指定的数据字段的值。 对于 GridView 控件,ClientIDRowSuffix 属性可以指定多个数据字段。 如果 ClientIDRowSuffix 属性为空白,则在末尾添加递增的行号,而非数据字段值。 各部分之间以下划线字符 (_) 分隔。

以上是MSDN的说法,但是经过试验,我发现Predictable的特性更应该是用这么个式子来表达:

Inherit[+"_"+ClientIDRowSuffix]

意思就是说,如果一个控件的ClientIDMode选中为Predictable,那么在ASP.NET生成该控件的ClientID时首先会去看该控件所属的父容器控件的ClientIDMode是什么值,然后先用该控件父容器控件的ClientIDMode规则生成该控件本身的ClientID,最后如果该控件所属的父容器控件或祖先容器控件是显示多个数据行的容器控件,还会根据父容器控件或祖先容器控件的ClientIDRowSuffix属性的值在该控件已生成的ClientID后面加上一个后缀字符串。

下面将几种情况逐一列出来单独解释:

<1>如果父容器控件的ClientIDMode值为AutoID

  • 如果父容器控件或祖先容器控件为显示多个数据行的容器控件,那么该控件的ClientID格式为:[父/祖先容器控件的ID+"_"+[行号格式+"_"]]+该控件自身ID+"_"+[ClientIDRowSuffix],其中ClientIDRowSuffix部分是什么后面会单独说明,其中:[父/祖先容器控件的ID+"_"+[行号格式+"_"]],就是该控件自身ClientIDMode值继承父容器控件ClientIDMode值AutoID生成的ClientID结果,其中的[行号格式+"_"]部分是否存在依赖于[父/祖先容器控件]部分是否是显示多个数据行的容器控件(这里不明白请看前面的AutoID部分)。
  • 如果父容器控件或祖先容器控件都不是显示多个数据行的容器控件,那么该控件的ClientID格式为:[父/祖先容器控件的ID+"_"]+该控件自身ID,可见这个格式就是该控件自身ClientIDMode值继承父容器控件ClientIDMode值AutoID生成的ClientID结果(这里不明白请看前面的AutoID部分)。

下面我就举一个父容器控件是多数据行容器控件且其ClientIDMode为AutoID的例子,将上面的代码再做更改,将Label1的ClientIDMode属性值改为Predictable,并且设置其父容器控件grd_Account的ClientIDMode为AutoID:

<asp:GridView ID="grd_Account" runat="server" AllowPaging="True"
  AutoGenerateColumns="False"
  DataKeyNames="Account Number" DataSourceID="sds_account" Height="63px"
  Width="676px" PageSize="5" ClientIDMode="AutoID" >
  <Columns>
    <asp:TemplateField HeaderText="Account Number" Sort ="Account Number">
      <ItemTemplate>
        <asp:Label ID="Label1" runat="server" Text="Logged" ClientIDMode="Predictable"></asp:Label>
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>

其生成的HTML代码为:

<table cellspacing="0" rules="all" border="1" id="grd_Account" style="height:63px;width:676px;border-collapse:collapse;">
  <tr>
  <th scope="col">Account Number</th>
  </tr>
  <tr>
  <td>
      <span id="grd_Account_ctl02_Label1_0">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="grd_Account_ctl03_Label1_1">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="grd_Account_ctl04_Label1_2">Logged</span>
    </td>
  </tr>
</table>

可以看到生成的Label的控件的ID诸如:grd_Account_ctl02_Label1_0正是上面所述格式:父容器控件的ID(grd_Account)+"_"+行号格式(ctl02)+"_"+该控件自身ID(Label1)+"_"+[ClientIDRowSuffix](0)。

<2>如果父容器控件的ClientIDMode值为Static

  • 如果父容器控件或祖先容器控件为显示多个数据行的容器控件,那么该控件的ClientID格式为:该控件自身ID+"_"+[ClientIDRowSuffix],其中ClientIDRowSuffix部分是什么后面会单独说明,其中:该控件自身ID,就是该控件自身ClientIDMode值继承父容器控件ClientIDMode值Static生成的ClientID结果(这里不明白请看前面的Static部分)。
  • 如果父容器控件或祖先容器控件都不是显示多个数据行的容器控件,那么该控件的ClientID格式为:该控件自身ID,可见这个格式就是该控件自身ClientIDMode值继承父容器控件ClientIDMode值Static生成的ClientID结果(这里不明白请看前面的Static部分)。

下面我就举一个父容器控件是多数据行容器控件且其ClientIDMode为Static的例子,将上面的代码再做更改,将Label1的ClientIDMode属性值改为Predictable,并且设置其父容器控件grd_Account的ClientIDMode为Static:

<asp:GridView ID="grd_Account" runat="server" AllowPaging="True"
  AutoGenerateColumns="False"
  DataKeyNames="Account Number" DataSourceID="sds_account" Height="63px"
  Width="676px" PageSize="5" ClientIDMode="Static" >
  <Columns>
    <asp:TemplateField HeaderText="Account Number" Sort ="Account Number">
      <ItemTemplate>
        <asp:Label ID="Label1" runat="server" Text="Logged" ClientIDMode="Predictable"></asp:Label>
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>

其生成的HTML代码为:

<table cellspacing="0" rules="all" border="1" id="grd_Account" style="height:63px;width:676px;border-collapse:collapse;">
  <tr>
  <th scope="col">Account Number</th>
  </tr>
  <tr>
  <td>
      <span id="Label1_0">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="Label1_1">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="Label1_2">Logged</span>
    </td>
    </tr>
</table>

可以看到生成的Label的控件的ID诸如:Label1_0正是上面所述格式:该控件自身ID(Label1)+"_"+[ClientIDRowSuffix](0)。

<3>如果父容器控件的ClientIDMode值为Predictable

  • 如果父容器控件或祖先容器控件为显示多个数据行的容器控件,那么该控件的ClientID格式为:父容器控件的ClientID+"_"+该控件自身ID+"_"+[ClientIDRowSuffix],其中ClientIDRowSuffix部分是什么后面会单独说明,可见这种情况才属于MSDN上所说的格式。
  • 如果父容器控件或祖先容器控件都不是显示多个数据行的容器控件,那么该控件的ClientID格式为:父容器控件的ClientID+"_"+该控件自身ID,可见这种情况才是MSDN上所说的格式。

下面我就举一个父容器控件是多数据行容器控件且其ClientIDMode为Predictable的例子,将上面的代码再做更改,将Label1的ClientIDMode属性值改为Predictable,并且设置其父容器控件grd_Account的ClientIDMode也为Predictable:

<asp:GridView ID="grd_Account" runat="server" AllowPaging="True"
  AutoGenerateColumns="False"
  DataKeyNames="Account Number" DataSourceID="sds_account" Height="63px"
  Width="676px" PageSize="5" ClientIDMode="Predictable" >
  <Columns>
    <asp:TemplateField HeaderText="Account Number" Sort ="Account Number">
      <ItemTemplate>
        <asp:Label ID="Label1" runat="server" Text="Logged" ClientIDMode="Predictable"></asp:Label>
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>

其生成的HTML代码为:

<table cellspacing="0" rules="all" border="1" id="grd_Account" style="height:63px;width:676px;border-collapse:collapse;">
  <tr>
  <th scope="col">Account Number</th>
  </tr>
  <tr>
  <td>
      <span id="grd_Account_Label1_0">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="grd_Account_Label1_1">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="grd_Account_Label1_2">Logged</span>
    </td>
    </tr>
</table>

可以看到生成的Label的控件的ID诸如:grd_Account_Label1_0正是上面所述格式:父容器控件的ClientID(grd_Account)+"_"+该控件自身ID(Label1)+"_"+[ClientIDRowSuffix](0)。

<4>如果父容器控件的ClientIDMode值为Inherit

这种情况没什么好说的,因为父容器控件的ClientIDMode值会继承其所在更上层的祖先容器控件的ClientIDMode值,继承后也属于上面三种情况之一。

最后来说说ClientIDRowSuffix部分是什么,如果父容器控件或祖先容器控件是显示多数据行的容器控件(后面会讨论到如果控件的ClientIDMode为Predictable,在判断该控件是否在显示多数据行的容器控件中时,会有一种特殊的穿透现象),那么父容器控件或祖先容器控件会有个属性叫ClientIDRowSuffix,比如本例中的GridView的ClientIDRowSuffix属性,这个属性的作用是为设定ClientIDMode值为Predictable的子控件生成ClientID的后缀字符串(就是上面那些ClientID格式中的ClientIDRowSuffix部分):

如果 ClientIDRowSuffix 属性为空白,则在已生成的子控件ClientID末尾添加递增的行号并在行号前面加上下划线字符 (_) 分隔,比如上面的例子中由于都没有在GridView上设置ClientIDRowSuffix属性,所以ClientIDRowSuffix为空白,那么生成的子控件ClientID最末位都有诸如_0、_1、_2等的递增行号。

此外还可以设置ClientIDRowSuffix 属性值为父容器控件或祖先容器控件中DataSource数据源中的字段,这样生成子控件ClientID的后缀字符串为ClientIDRowSuffix 指定字段在该行的数据值,并且ClientIDRowSuffix 属性可指定多个DataSource数据源中的数据字段,那么在生成子控件ClientID时会将每个数据字段在该行的值用下划线字符 (_) 进行分隔然后作为ClientID后缀字符串。

现在就举个例子,将上面的代码再做更改将Label1的ClientIDMode属性值改为Predictable,并且设置其父容器控件grd_Account的ClientIDMode也为Predictable,并且将grd_Account的ClientIDRowSuffix设置为数据源sds_account的Account Number字段:

<asp:GridView ID="grd_Account" runat="server" AllowPaging="True"
  AutoGenerateColumns="False"
  DataKeyNames="Account Number" DataSourceID="sds_account" Height="63px"
  Width="676px" PageSize="5" ClientIDMode="Predictable" ClientIDRowSuffix="Account Number" >
  <Columns>
    <asp:TemplateField HeaderText="Account Number" Sort ="Account Number">
      <ItemTemplate>
        <asp:Label ID="Label1" runat="server" Text="Logged" ClientIDMode="Predictable"></asp:Label>
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>

其生成的HTML代码为:

<table cellspacing="0" rules="all" border="1" id="grd_Account" style="height:63px;width:676px;border-collapse:collapse;">
  <tr>
  <th scope="col">Account Number</th>
  </tr>
    <tr>
  <td>
      <span id="grd_Account_Label1_1060">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="grd_Account_Label1_1200">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="grd_Account_Label1_1510">Logged</span>
    </td>
    </tr>
</table>

可以看到生成子控件的ClientID的后缀字符串为Account Number字段在GridView上每行的值:1060、1200、1500,其不再是递增的行号.

EX:最后Predictable还有一个很特别的特性:

当控件的ClientIDMode为Predictable且该控件在多个嵌套的容器控件中时,判断该控件是否在显示多数据行的容器控件中时,会具有层次穿透性,它不但会考察父容器控件,还会考察祖先容器控件。

下面就举个例子来说明这种情况,首先grd_Account为显示多数据行的容器控件,它的ClientIDMode设置为Static,在它内部有一个ID为LoginView1的LoginView,我们知道LoginView也是容器性控件,只不过它不是显示多数据行的容器控件,这里设置LoginView1的ClientIDMode属性为Predictable,在LoginView1里面再放置一个ID为Label1的Label,它的ClientIDMode没有设置,所以其值也默认继承为Predictable,下面是代码:

<asp:GridView ID="grd_Account" runat="server" AllowPaging="True"
  AutoGenerateColumns="False"
  DataKeyNames="Account Number" DataSourceID="sds_account" Height="63px"
  Width="676px" PageSize="5" ClientIDMode="Static" >
  <Columns>
    <asp:TemplateField HeaderText="Account Number" Sort ="Account Number">
      <ItemTemplate>
        <asp:LoginView ID="LoginView1" runat="server" ClientIDMode="Predictable" >
          <LoggedInTemplate>
            <asp:Label ID="Label1" runat="server" Text="Logged"></asp:Label>
          </LoggedInTemplate>
        </asp:LoginView>
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>

可以看到在嵌套层次结构中,由于LoginView1所属的父容器控件grd_Account是显示多数据行的容器控件,所以LoginView1的ClientID应该是诸如:LoginView1_0、LoginView1_1等有ClientIDRowSuffix部分的格式,这没有问题,但是按道理来说Label1所在的父容器控件LoginView1不是显示多数据行的容器控件,那么Label1生成的ClientID 应该是诸如LoginView1_0_Label1、LoginView1_1_Label1等这样的没有ClientIDRowSuffix部分的格式,但是为我们来看一下生成的HTML代码:

<table cellspacing="0" rules="all" border="1" id="grd_Account" style="height:63px;width:676px;border-collapse:collapse;">
  <tr>
  <th scope="col">Account Number</th>
  </tr>
  <tr>
  <td>
      <span id="LoginView1_0_Label1_0">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="LoginView1_1_Label1_1">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="LoginView1_2_Label1_2">Logged</span>
    </td>
  </tr>
</table>

可以看到生成的Label1的ClientID都带表示递增行号的后缀字符串0、1、2等(此外请注意LoginView不会产生HTML代码),也就是有ClientIDRowSuffix部分。

我们再将grd_Account的ClientIDRowSuffix属性更改为数据源中的Account Number字段后再来看看生成的HTML代码:

<table cellspacing="0" rules="all" border="1" id="grd_Account" style="height:63px;width:676px;border-collapse:collapse;">
  <tr>
  <th scope="col">Account Number</th>
  </tr>
  <tr>
  <td>
      <span id="LoginView1_1060_Label1_1060">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="LoginView1_1200_Label1_1200">Logged</span>
    </td>
  </tr>
  <tr>
  <td>
      <span id="LoginView1_1510_Label1_1510">Logged</span>
    </td>
  </tr>
</table>

可以看到生成的Label1的ClientID也都带ClientIDRowSuffix部分,只不过ClientIDRowSuffix部分现在是数据源中Account Number字段的值。

由此可见在判断Label1是否在显示多数据行的容器控件中时,判定机制进行了穿透,即假如有这么一组嵌套的容器控件:Control_1<-Control_2<-Control_3<-.......<-Control1_n-1<-Control_n,其中Control_n的ClientIDMode设置或继承为Predictable,且其中Control_2到Control1_n-1都不是显示多数据行的容器控件,只有最外层的Control_1是显示多数据行的容器控件,那么在判定最里面的Control_n是否在显示多数据行的容器控件时,参考的是从里到外第一个是显示多数据行的容器控件Control_1(即从里到外只要任意一个容器控件是显示多数据行的容器控件,就认为Control_n是在显示多数据行的容器控件中),并且Control_n的后缀字符串部分参考的也是Control_1的ClientIDRowSuffix属性,从而忽略中间那些不是显示多数据行的容器控件(Control_2到Control1_n-1),所以控件的ClientIDMode属性为Predictable时,就是用这种穿透判定来判断该控件是否在显示多数据行的容器控件中的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • ASP.NET 4.0配置文件中的ClientIDMode属性详解

    时光流逝,我们心爱的ASP.NET也步入了4.0的时代,微软在ASP.NET 4.0中对很多特性做了修改.比如我将要讨论的控件ID机制就是其中之一. 在ASP.NET 4.0之前我们总是要为控件的ClientID头疼,比如明明一个叫lblName的Label放在一个叫做grd的GridView里面后,在页面上改Label的ID就变成了诸如grd_clt02_lblName的一长串字符串,如果我们在前台想在使用JS的时候找到该Label,我们不得不用到C#脚本来获得该Label在前台的确切ID,诸

  • JSP Spring配置文件中传值的实例详解

    JSP Spring配置文件中传值的实例详解 通过spring提供方法,在配置文件中取传值 调用get方法  targetObject :指定调用的对象       propertyPath:指定调用那个getter方法 例1: public class Test1 { private String name = "nihao"; public String getName() { return name; } } Xml代码 <bean id="t1" cl

  • Javascript中window.name属性详解

    关于window下自带name的属性 不知道大家有没有发现这样一种情况 在控制台里直接输出未声明变量,正常情况应该是会报错的,而且声明未赋值的变量输出应该是undefined var a; //undefined b; //报错 但是偏偏就个别特例,就是name属性 其实window自身就带有name这个属性,在控制台输入window可以可以看到 打开 往下翻就可以找到 window.name直译过来是窗口名字,主要用于为超链接和表单设置目标(targets),什么意思呢,我们做个案例 建立两个

  • ASP.NET Core 2.2中的Endpoint路由详解

    Endpoint路由 在ASP.NET Core 2.2中,新增了一种路由,叫做 Endpoint (终结点)路由.本文将以往的路由系统称为 传统路由 . 本文通过源码的方式介绍传统路由和 Endpoint 路由部分核心功能和实现方法,具体功能上的差异见 官方文档 . 在升级到ASP.NET Core 2.2后,会自动启用 Endpoint 路由.如果要恢复以往的实现逻辑,需要加入以下代码: services.AddMvc(options => options.EnableEndpointRou

  • vue 2.0项目中如何引入element-ui详解

    前言 本文主要介绍了关于在vue 2.0项目中引入element-ui的相关内容,从新建vue项目到引入组件Element介绍的非常详细,下面话不多说了,来一起看看详细的介绍吧. 一.新建项目 1.查看 node和npm是不是已经安装好命令:node -v  npm -v (没有安装的先安装环境); 2.npm install -g cnpm --registry=https://registry.npm.taobao.org  (安装国内的淘宝镜像文件,后面的安装npm可以全部改为cnpm)

  • Android 8.0系统中通知栏的适配详解

    大家好,今天我们继续来学习Android 8.0系统的适配. 之前我们已经讲到了,Android 8.0系统最主要需要进行适配的地方有两处:应用图标和通知栏.在上一篇文章当中,我们学习了Android 8.0系统应用图标的适配,还没有看过这篇文章的朋友可以先去阅读 Android应用图标微技巧,8.0系统中应用图标的适配 . 那么本篇文章,我们自然要将重点放在通知栏上面了,学习一下Android 8.0系统的通知栏适配. 其实在8.0系统之前,还有一次通知栏变动比较大的版本,就是5.0系统.关于

  • Spring Cloud 中@FeignClient注解中的contextId属性详解

    目录 @FeignClient注解中的contextId属性 解决方法一 解决方法二 FeignClient注解及参数问题 问题背景 解决办法 @FeignClient注解中的contextId属性 在使用@FeignClient注解前,我们需要先引入其相关依赖,版本为3.0.1 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter

  • Vue中的computed属性详解

    目录 插值表达式 methods computed 总结 今天来说说vue中的计算属性computed,为了更好的理解计算属性的好处,我们先通过一个案例来慢慢 了解计算属性,有如下案例:定义两个输入框以及一个span标签,span标签中的内容为两个输入框中的值,span标签中的内容随着输入框中的内容变化而变化 插值表达式 我们先用插值表达式的方法来实现这一效果 <body> <div id="app"> 姓: <input type="text&

  • 如何直接访问php实例对象中的private属性详解

    前言 本文主要介绍了关于如何直接访问php实例对象中private属性的相关内容,在介绍关键部分之前,我们先回顾一下php面向对象的访问控制. 对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的.被定义为公有的类成员可以在任何地方被访问.被定义为受保护的类成员则可以被其自身以及其子类和父类访问.被定义为私有的类成员则只能被其定义所在的类访问. 类属性必须定义为公有,受保护,私有之一.如果用 var 定义,则被视为公

  • Android中的windowSoftInputMode属性详解

    在前面的一篇文章中,简单的介绍了一下如何实现软键盘不自动弹出,使用的方法是设置android:windowSoftInputMode属性.那么,这个属性到底是干什么的,他有什么作用呢?今天这篇文章,就是探索android:windowSoftInputMode属性的作用的. 首先,我们从这个属性的名称中,可以很直观的看出它的作用,这个属性就是来设置窗口软键盘的交互模式的. android:windowSoftInputMode属性一共有9个取值,分别是: stateUnspecified,sta

随机推荐