asp.net2 无刷新动态加载树

因为树比较大(可能有几千个点),一次全部加载速度不能接受。因此方案是动态加载:开始只列出少量一层数据,然后随着使用者不断点击节点,动态载入下级节点,这样因为每次点击只载入几十个节点,速度就可以接受了。

 

 

以下代码从 msdn 复制,可通过 treeview 控件的 PopulateNodesFromClient 等属性的说明找到这段代码。如果完全复制的话,执行时的效果是一个完全展开、写进所有数据的树,这看起来根本不是想要的效果。这时只需要改一个地方:增加树的 ExpandDepth="0" 属性。想想也是,默认树完全展开,不就是开始看到的效果?

加入了 ExpandDepth="0" 后,效果是,树只有初始节点,任何需要动态加入到节点都没有。这时点开一节点(+ 号),子节点无刷新加入;下级类似。查看 html 源文件,只有初始节点的 html 码,ok,这就是想要的。

有一点注意,通过正取设置 select,然后通过按钮或其它方式选中,把选中结果发给服务器,这时服务端程序可取得选中,然后此时返回的页面是包括树的所有已经加载数据的,即同服务器往返一次后,在查看 html 源,则树中所有已加入数据都在 html 里。这样往返的成本仍然很高,不过毕竟省下了读取数据环节。

通过 .net ajax 的 updatepanel 当然避免不了这些往返成本,可以通过 子框架,使树指向框架,这样就避免了树的往返,不过页面设计就分散了。。。

 

<%@ Page Language="C#" %>

<%@ Import Namespace="System.Data" %>

<%@ Import Namespace="System.Data.SqlClient" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

 

  void PopulateNode(Object sender, TreeNodeEventArgs e)

  {

    // Call the appropriate method to populate a node at a particular level.

    switch(e.Node.Depth)

    {

      case 0:

        // Populate the first-level nodes.

        PopulateCategories(e.Node);

        break;

      case 1:

        // Populate the second-level nodes.

        PopulateProducts(e.Node);

        break;

      default:

        // Do nothing.

        break;

    }

 

  }

 

  void PopulateCategories(TreeNode node)

  {

 

    // Query for the product categories. These are the values

    // for the second-level nodes.

    DataSet ResultSet = RunQuery("Select CategoryID, CategoryName From Categories");

 

    // Create the second-level nodes.

    if(ResultSet.Tables.Count > 0)

    {

 

      // Iterate through and create a new node for each row in the query results.

      // Notice that the query results are stored in the table of the DataSet.

      foreach (DataRow row in ResultSet.Tables[0].Rows)

      {

 

        // Create the new node. Notice that the CategoryId is stored in the Value property

        // of the node. This will make querying for items in a specific category easier when

        // the third-level nodes are created.

        TreeNode newNode = new TreeNode();

        newNode.Text = row["CategoryName"].ToString();

        newNode.Value = row["CategoryID"].ToString();       

 

        // Set the PopulateOnDemand property to true so that the child nodes can be

        // dynamically populated.

        newNode.PopulateOnDemand = true;

 

        // Set additional properties for the node.

        newNode.SelectAction = TreeNodeSelectAction.Expand;

 

        // Add the new node to the ChildNodes collection of the parent node.

        node.ChildNodes.Add(newNode);

 

      }

 

    }

 

  }

 

  void PopulateProducts(TreeNode node)

  {

 

    // Query for the products of the current category. These are the values

    // for the third-level nodes.

    DataSet ResultSet = RunQuery("Select ProductName From Products Where CategoryID=" + node.Value);

 

    // Create the third-level nodes.

    if(ResultSet.Tables.Count > 0)

    {

 

      // Iterate through and create a new node for each row in the query results.

      // Notice that the query results are stored in the table of the DataSet.

      foreach (DataRow row in ResultSet.Tables[0].Rows)

      {

 

        // Create the new node.

        TreeNode NewNode = new TreeNode(row["ProductName"].ToString());

 

        // Set the PopulateOnDemand property to false, because these are leaf nodes and

        // do not need to be populated.

        NewNode.PopulateOnDemand = false;

 

        // Set additional properties for the node.

        NewNode.SelectAction = TreeNodeSelectAction.None;

 

        // Add the new node to the ChildNodes collection of the parent node.

        node.ChildNodes.Add(NewNode);

 

      }

 

    }

 

  }

 

  DataSet RunQuery(String QueryString)

  {

 

    // Declare the connection string. This example uses Microsoft SQL Server

    // and connects to the Northwind sample database.

    String ConnectionString = "server=localhost;database=NorthWind;Integrated Security=SSPI";

 

    SqlConnection DBConnection = new SqlConnection(ConnectionString);

    SqlDataAdapter DBAdapter;

    DataSet ResultsDataSet = new DataSet();

 

    try

    {

 

      // Run the query and create a DataSet.

      DBAdapter = new SqlDataAdapter(QueryString, DBConnection);

      DBAdapter.Fill(ResultsDataSet);

 

      // Close the database connection.

      DBConnection.Close();

 

    }

    catch(Exception ex)

    {

 

      // Close the database connection if it is still open.

      if(DBConnection.State == ConnectionState.Open)

      {

        DBConnection.Close();

      }

 

      Message.Text = "Unable to connect to the database.";

 

    }

 

    return ResultsDataSet;

 

  }

 

  protected void Button1_Click(object sender, EventArgs e)

  {

   Response.Write(LinksTreeView.SelectedNode.Value);

  }

</script>

 

<html xmlns="http://www.w3.org/1999/xhtml" >

  <head id="Head1" runat="server">

    <title>TreeView PopulateNodesFromClient Example</title>

</head>

<body>

    <form id="form1" runat="server">

 

      <h3>TreeView PopulateNodesFromClient Example</h3>

 <asp:Button ID="Button1" runat="server" Text="Button" οnclick="Button1_Click" />

      <asp:TreeView id="LinksTreeView"

        Font-Names= "Arial"

        ForeColor="Blue"

        EnableClientScript="true"

        PopulateNodesFromClient="true" 

        OnTreeNodePopulate="PopulateNode"

        runat="server" ExpandDepth="0">

 

        <Nodes>

 

          <asp:TreeNode Text="Inventory"

            SelectAction="Expand" 

            PopulateOnDemand="true" Value="-32768" />

 

        </Nodes>

 

      </asp:TreeView>

 

      <br /><br />

 

      <asp:Label id="Message" runat="server"/>

 

    </form>

  </body>

</html>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ASP.NET刷新上传 很不错的多文件 带进度条的 无刷新上传 绝对好用~~~ <script> var QuickUpload = function(file, options) { this.file = $$(file); this._sending = false;//是否正在上传 this._timer = null;//定时器 this._iframe = null;//iframe对象 this._form = null;//form对象 this._inputs = {};//input对象 this._fFINISH = null;//完成执行函数 $$.extend(this, this._setOptions(options)); }; QuickUpload._counter = 1; QuickUpload.prototype = { //设置默认属性 _setOptions: function(options) { this.options = {//默认值 action: "",//设置action timeout: 0,//设置超时(秒为单位) parameter: {},//参数对象 onReady: function(){},//上传准备时执行 onFinish: function(){},//上传完成时执行 onStop: function(){},//上传停止时执行 onTimeout: function(){}//上传超时时执行 }; return $$.extend(this.options, options || {}); }, //上传文件 upload: function() { //停止上一次上传 this.stop(); //没有文件返回 if ( !this.file || !this.file.value ) return; //可能在onReady中修改相关属性所以放前面 this.onReady(); //设置iframe,form和表单控件 this._setIframe(); this._setForm(); this._setInput(); //设置超时 if ( this.timeout > 0 ) { this._timer = setTimeout( $$F.bind(this._timeout, this), this.timeout * 1000 ); } //开始上传 this._form.submit(); this._sending = true; }, //设置iframe _setIframe: function() { if ( !this._iframe ) { //创建iframe var iframename = "QUICKUPLOAD_" + QuickUpload._counter++, iframe = document.createElement( $$B.ie ? "<iframe name=\"" + iframename + "\">" : "iframe"); iframe.name = iframename; iframe.style.display = "none"; //记录完成程序方便移除 var finish = this._fFINISH = $$F.bind(this._finish, this); //iframe加载完后执行完成程序 if ( $$B.ie ) { iframe.attachEvent( "onload", finish ); } else { iframe.onload = $$B.opera ? function(){ this.onload = finish; } : finish; } //插入body var body = document.body; body.insertBefore( iframe, body.childNodes[0] ); this._iframe = iframe; } }, //设置form _setForm: function() { if ( !this._form ) { var form = document.createElement('form'), file = this.file; //设置属性 $$.extend(form, { target: this._iframe.name, method: "post", encoding: "multipart/form-data" }); //设置样式 $$D.setStyle(form, { padding: 0, margin: 0, border: 0, backgroundColor: "transparent", display: "inline" }); //提交前去掉form file.form && $$E.addEvent(file.form, "submit", $$F.bind(this.dispose, this)); //插入form file.parentNode.insertBefore(form, file).appendChild(file); this._form = form; } //action可能会修改 this._form.action = this.action; }, //设置input _setInput: function() { var form = this._form, oldInputs = this._inputs, newInputs = {}, name; //设置input for ( name in this.parameter ) { var input = form[name]; if ( !input ) { //如果没有对应input新建一个 input = document.createElement("input"); input.name = name; input.type = "hidden"; form.appendChild(input); } input.value = this.parameter[name]; //记录当前input newInputs[name] = input; //删除已有记录 delete oldInputs[name]; } //移除无用input for ( name in oldInputs ) { form.removeChild( oldInputs[name] ); } //保存当前input this._inputs = newInputs; }, //停止上传 stop: function() { if ( this._sending ) { this._sending = false; clearTimeout(this._timer); //重置iframe if ( $$B.opera ) {//opera通过设置src会有问题 this._removeIframe(); } else { this._iframe.src = ""; } this.onStop(); } }, //销毁程序 dispose: function() { this._sending = false; clearTimeout(this._timer); //清除iframe if ( $$B.firefox ) { setTimeout($$F.bind(this._removeIframe, this), 0); } else { this._removeIframe(); } //清除form this._removeForm(); //清除dom关联 this._inputs = this._fFINISH = this.file = null; }, //清除iframe _removeIframe: function() { if ( this._iframe ) { var iframe = this._iframe; $$B.ie ? iframe.detachEvent( "onload", this._fFINISH ) : ( iframe.onload = null ); document.body.removeChild(iframe); this._iframe = null; } }, //清除form _removeForm: function() { if ( this._form ) { var form = this._form, parent = form.parentNode; if ( parent ) { parent.insertBefore(this.file, form); parent.removeChild(form); } this._form = this._inputs = null; } }, //超时函数 _timeout: function() { if ( this._sending ) { this._sending = false; this.stop(); this.onTimeout(); } }, //完成函数 _finish: function() { if ( this._sending ) { this._sending = false; this.onFinish(this._iframe); } } } </script>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值