如果在formPanel中使用了checkBox,radioBox时,在提交表单时使用formPanel.getForm().submit()来提交数据时,如果单选框和复选框未选中时,则extjs是不会提交这些控件的。在postdata中根本就不存在这些控件的任何影子。可以通过firebug来查看提交的数据。
posted @ 2010-02-03 22:06 Kevin163 阅读(1398) 评论(0) 编辑
本文章主要介绍jquery插件中的treeview插件通过ajax异步从服务器上下载所需json字符串的实现,服务器端使用asp.net mvc实现。
treeview插件的官方demo地址:http://jquery.bassistance.de/treeview/demo/
实现步骤:
一、新建一JQueryTreeviewController,其默认的Index View内容如下:
<link rel="stylesheet" href="/Content/jquery.treeview.css" />
 
 <script src="/Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>
 <script src="/Scripts/jquery.treeview.js" type="text/javascript"></script>
 <script src="/Scripts/jquery.treeview.async.js" type="text/javascript"></script>
 
 <script type="text/javascript">
 $(document).ready(function(){
  $("#black").treeview({
   url: '<%=Url.Action("GetMenuTree","JQueryTreeview") %>'
  });
 });
 </script>
    <h2>TreeViewIndex</h2>
    <ul id="black" class="navigateFiletree">
 </ul>
从以上代码中可以看出,获取此视图后,当页面就绪时将调用GetMenuTree action方法来获取treeview插件所需要的json字符串,并且自动生成树形。
注:代码中引用的js和css文件,在下载的treeview插件包中可以找到。
二、实现GetMenuTree action方法,代码如下:

public JsonStringResult GetMenuTree()
        {
            string sql = "SELECT [ModuleID],[SuperModuleID] FROM [SysModules]";
            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString))
            {
                conn.Open();
                SqlCommand cmd = conn.CreateCommand();
                cmd.CommandText = sql;
                DataTable dt = new DataTable();
                SqlDataReader reader = cmd.ExecuteReader();
                dt.Load(reader);
                reader.Close();
                conn.Close();

                return this.JsonString(JQTreeHelper.GetJsonString(dt, "ModuleID", "ModuleID", "SuperModuleID", ""));
            }
        }
其作用就是从数据库中读取出需要显示成树形的数据,并且调用JQTreeHelper来生成相应的json字符串,其返回结果中的JsonStringResult 是自定义的一个result类,其作用基本与系统自带的JsonResult相同,只是输出文本时不再进行json序列化而已。
三、实现JQTreeHelper类,代码如下:
    /// <summary>
    /// jquery插件中的treeview控件的帮助类,用于生成treeview控件所需要的html代码结构
    /// </summary>
    public static class JQTreeHelper
    {
        public static List<JQTreeNode> GetJsonData(DataTable dtAllNodes,string idColumnName,string textColumnName,string parentIdColumnName,string rootNodeParentIdValue)
        {
            List<JQTreeNode> rootNodes = new List<JQTreeNode>();
            DataView dvRootNodes = new DataView(dtAllNodes);
            dvRootNodes.RowFilter = parentIdColumnName + "='" + rootNodeParentIdValue + "'";
            foreach (DataRowView dv in dvRootNodes)
            {
                JQTreeNode node = new JQTreeNode();
                if (dv[idColumnName] != DBNull.Value)
                {
                    node.id = dv[idColumnName].ToString();
                }
                node.text = dv[textColumnName].ToString();
                node.children = GetJsonData(dtAllNodes, idColumnName, textColumnName, parentIdColumnName, dv[idColumnName].ToString());
                rootNodes.Add(node);
            }
            return rootNodes;
        }
        public static string GetJsonString(DataTable dtAllNodes, string idColumnName, string textColumnName, string parentIdColumnName, string rootNodeParentIdValue)
        {
            List<JQTreeNode> actual;
            actual = GetJsonData(dtAllNodes, idColumnName, textColumnName, parentIdColumnName, rootNodeParentIdValue);
            //序列化后,由于默认将所有字段都序列化输出,所以需要将没有赋值取默认值的字段替换为空,以此来减少输出的字符数
            StringBuilder result = new StringBuilder();
            new JavaScriptSerializer().Serialize(actual, result);
            result.Replace("\"id\":null,", "");
            result.Replace(",\"expanded\":false", "");
            result.Replace(",\"hasChildren\":false", "");
            result.Replace(",\"classes\":null", "");
            result.Replace(",\"children\":null", "");
            return result.ToString();
        }
    }
    /// <summary>
    /// jquery插件中的treeview控件进行ajax请求时返回的json数据对象
    /// </summary>
    public class JQTreeNode
    {
        /// <summary>
        /// 树节点id
        /// </summary>
        public string id { get; set; }
        /// <summary>
        /// 树节点文本
        /// </summary>
        public string text { get; set; }
        /// <summary>
        /// 是否展开
        /// </summary>
        public bool expanded { get; set; }
        /// <summary>
        /// 是否有子节点
        /// </summary>
        public bool hasChildren { get; set; }
        /// <summary>
        /// cssclass类名称
        /// </summary>
        public string classes { get; set; }
        /// <summary>
        /// 子节点集合
        /// </summary>
        public List<JQTreeNode> children { get; set; }
    }
到此代码就全部结束。

Kevin

 

posted @ 2009-10-08 16:49 Kevin163 阅读(1767) 评论(1) 编辑

      最近在做酒店的网上会员自助服务项目,其中有一项是介绍会员手册的。由于此项目需要做成产品,而每家酒店的会员手册又不相同,如何做到既能通用又能由用户进行个性化修改而不修改程序呢?
      最后采取了用xml的方法,将会员手册的数据保存到xml文件中,由于会员手册有可能会包含图片,表格等html数据,如果我的xml文件考虑得太细则不能通用,于是我将xml文件设置成以下格式:
<?xml version="1.0" encoding="utf-8" ?>
<handbook>
 <title>如何成为会员</title>
 <content>
  <![CDATA[
  <table>
   <tr>
    <td>1</td>
    <td>网上直接注册</td>
   </tr>
   <tr>
    <td>2</td>
    <td>前台直接办理</td>
   </tr>
   <tr>
    <td>3</td>
    <td>传真办理</td>
   </tr>
  </table>  
  ]]>
 </content>
</handbook>

只保留了一个标题和一个内容项,而内容项里需要注意的是包含有:<![CDATA[]]>标签,将需要包含的html代码直接放在其中即可。

在输出的时候进行xsl转换,转换时由于包含有html代码,所以需要将输出项的“禁止输出编码转换”设置为yes,这样在输出的时候就会将html代码直接输出,ie解析的时候就能正常显示相应的结果了。

xslt文件如下:
<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
 <table>
  <tr>
   <td align="center">
    <xsl:value-of select="handbook/title"/>
   </td>
  </tr>
  <tr>
   <td align="left">
    <xsl:value-of disable-output-escaping="yes" select="handbook/content"/>
   </td>
  </tr>
 </table>
</xsl:template>

</xsl:stylesheet>

在会员手册的详细页面中,放置一个XML的控件,设置其DocumentSource,TransformSource属性后调用databind方法即可。当用户想要更改会员手册内容的时候,只需要更改xml文件即可。程序无需再修改和编译。

posted @ 2007-02-11 10:16 Kevin163 阅读(1490) 评论(0) 编辑
      前段时间自己写了个工具栏控件,却发现有时点击工具栏按钮时,对应的事件会被执行两次,但并不是每次都会。
      通过调试检查代码,并没有发现错误,并且页面的响应也完全正常,但就是事件会执行两次。百思不得其解,于是就上网寻找答案,结果发现网上介绍此乃是.Net的一个bug(详细请参考:http://www.cnblogs.com/bluewater/archive/2006/11/21/567871.html),ImageButton会导致传递IE向IIS服务器POST两次数据,其中第一次传回服务器的数据缺少鼠标指针位置数据,第二次传回服务器的数据是正确的。(注:经测试发现,只有将ImageButton放在其他容器控件的内部时才会发生这样的事情,如果单独使用并不会),导致控件中的事件也响应了两次。既然如此又想要ImageButton的美观,又要能完成事件,于是就将ImageButton更改成了HyperLink,设置其图片地址,并且将其客户端OnClick事件连接上回发脚本即可实现事件。
 
     在此提醒大家一下,使用ImageButton作为其他控件的子控件时需要注意,为了避免出现莫名错误,建议还是在其他控件内部不要使用ImageButton,直到微软有补丁推出。
posted @ 2007-02-05 23:06 Kevin163 阅读(489) 评论(1) 编辑

      在内容页中如何调用母版页上的内容大家想必都已经知道,这里我也不再啰嗦。我想介绍给大家的方法是如何在母版页中如何调用内容页的方法。
       母版页给我们带来了很多方便性,但也带来了一个问题:在设计母版页的时候,总会碰到需要在母版页中调用内容页的方法,但此时内容页尚未设计,如何调用呢?下面就让我用一个实例给大家讲解一下:
      母版页:MasterPage.master的页面代码如下:
<body>
    <form id="form1" runat="server">
    <table>
        <tr>
            <td>
                <asp:Button ID="CallContentMethod" runat="server" OnClick="CallContentMethod_Click"
                    Text="调用内容页方法" />
                <asp:Label ID="welcomeMessage" runat="server" Text="这里将显示内容页的欢迎信息"></asp:Label></td>
        </tr>
        <tr>
            <td>
                <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
                </asp:contentplaceholder>
            </td>
        </tr>
    </table>
    </form>
</body>
其中有一个按钮和一个文本,其中的文本用来显示内容页的欢迎信息,按钮用来调用内容页的方法,但此时内容页并不存在,那么按钮的单击事件代码如何写呢?
      这里我们需要引入一个页面基类的概念,想必大家都清楚;aspx页面只要求后台类是继承此Page类即可。所以我们先添加一个继承自Page的页面基类BasePage,然后让页面继承自我们BasePage并重写相关方法,利用运行时的动态性来解决此问题。相关代码如下:
BasePage.cs:
public class BasePage :Page
{
    /// <summary>
    /// 输出每个内容页的欢迎信息,内容页继承此类并重写此方法即可。此方法会由母版页自动调用
    /// </summary>
    public virtual string SayHello()
    {
        return "这是页面基类返回的欢迎信息!";
    }
}
母版页的后台代码如下:
    BasePage currentPage = null;
    protected void Page_Load(object sender, EventArgs e)
    {
        currentPage = Page as BasePage;
    }
    protected void CallContentMethod_Click(object sender, EventArgs e)
    {
        if (currentPage != null)
        {
            welcomeMessage.Text = currentPage.SayHello();
        }
    }
此处母版页中定义一个成员变量指向BasePage,在PageLoad中将实际运行的页面进行转型,这样在按钮的单击事件中就可以调用BasePage定义的SayHello方法了。又由于此方法是虚方法,在运行时绑定具体方法,即可实现我们的要求。
下面是内容页的代码:
Default.aspx.cs:
//注意类一定要继承自自定义的基类,否则母版页中转型会失败
public partial class Template_Default : BasePage
//重写欢迎信息方法
    public override string SayHello()
    {
        return "这是来自内容页的欢迎信息!";
    }


通过以上的步骤,我们就可以轻松实现在母版页中调用内容页的方法。如果想自动调用,只需要在母版页的Page_Load方法中转型后直接调用相关方法即可。

如果大家有更好的方法欢迎一起讨论!!!

posted @ 2007-02-03 11:43 Kevin163 阅读(5007) 评论(7) 编辑