ASP.NET基本网站结构导航

时间:2012-12-06 10:05:57

标签: ajax asp.net-mvc navigation

我现在浏览了许多论坛以回答一个非常基本的问题,但令我惊讶的是,我找不到大多数网站使用的非常基本设计的好例子。我不是编程的新手,但是不久之前我用它做了更多的工作,我对ASP.NET完全不熟悉。我目前正在使用VS2010并从头开始构建ASP.NET MVC 3站点。该网站启用了AJAX,我目前正在使用左窗格导航的Root控件和顶部选项卡导航的TabContainer。

到目前为止,所有内容都包含在一个母版页中,基本问题是当在左/上菜单中选择导航链接时,整个页面会重新加载并销毁导航菜单的状态。此外,完全没有必要的闪烁,我认为没有理由重新加载整个页面,我只想更改“主区域”的内容而不触摸导航菜单。

网站结构目前使用<DIV>元素构建,这使得设计非常简单,CSS文件结构提供了极大的灵活性和控制力。根据建议,我想尽我所能避免过时的解决方案,如IFrames。我想以现代和灵活的方式为如何做到这一点奠定基础,尽可能少的妥协。这很重要,因为我已经启动的系统可能会在通过一系列决策论坛之后由整个团队进行。

我说的非常广泛地浏览了解决方案,并且发现了很多关于母版页概念的解释,这些解释让我输入了我的问题似乎:我的导航菜单被绑定到母版页,母版页实际上只是一个“用户控件”,它紧密地连接到内容页面,当我选择导航链接时,这些合并的页面会重新加载。这不应该发生,这是不可接受的。

我还尝试在“!IsPostBack”条件下包装导航面板的加载,但我得出的结论是问题不是PostBack:s,问题是点击链接/ treelink左侧菜单中的/ accordion窗格确实请求一个全新的页面,所以一切都重新加载,前一个状态丢失了。当然,我可以编写代码来存储状态并提供具有最后状态的“新页面”,如果没有其他可能的话,这将是一个解决方案;但我真的不想重新加载整个页面;我只想重新加载“主要区域”以减少带宽需求并避免闪烁。

所以我搜索了只更新“主要内容contentplaceholder”的方法,我看到很多关于这个主题的问题,但很少有好的答案,特别是当我想在主要区域更改整个aspx页面时,只需更新一些控件(或动态创建新控件/删除旧控件等)。改变整个aspx页面的冲动的原因是不同的页面将提供不同的功能,仅通过操作一些控件是不够的,但主要区域应该加载另一个aspx页面 - 从开发组织的角度来看它也是很好,因为不同的开发人员可以在完整的应用程序中处理不同的功能区域。

我愿意放弃整个母版页策略,或使用嵌套母版页,或在非母版页中包装母版页,或使用更新面板,或使用跨页面贴图等。但我找不到任何可以用作开头的实际工作的例子。

而且,由于这基本上只是在这一点上,只有客户端更新,我真的不明白为什么这应该变得如此棘手的东西。

所以,非常简单地说我的问题是:你认为什么是设计一个网站的基本策略,我有导航菜单(顶部和左部),可以将新的aspx页面加载到某个区域(主要区域)并且只更新此区域而不是整个站点。

如果你可以向我提供一些这方面的描述,当然最好是一些演示网站,其中只有一个网站的一部分用新页面而不是整页更新 - 就这么简单! - 当这非常受欢迎时。花了三天时间浏览一个好的推荐,我只是越来越困惑......: - (

非常感谢指示。

/ DT

2 个答案:

答案 0 :(得分:0)

我会选择母版页布局。有一个ContentPlaceHolder用于导航(尽可能多),另一个用于主要内容。然后,您可以使用JQuery.ajax()之类的内容或UpdatePanel中内置的ASP.NET在需要时将内容加载到主ContentPlaceHolder中。

关于内容本身,我会使用UserControls(.ascx文件)。您可以将命令传递到默认页面,告诉它要加载哪个Control,然后加载它。

我个人会使用ASP.NET UpdatePanel,因为您可以强制它使用UpdatePanel.Update();加载新内容。

有一点需要注意的是,如果这是一个需要搜索引擎优化的实际网站,可能很难做到,因为网址不会改变,所以SEO会受到影响。

这是一个广泛的例子,但HTH。

编辑:

我会做两件事:

  1. PlaceHolder添加到default.aspx(在UpdatePanel中),并将其作为公共var暴露在后面的代码中,以便可以从外部访问。
  2. 公开UpdatePanel以便可以从外部访问;
  3. 所以在默认情况下你会有类似的东西:

    <asp:Content id="Content1" runat="server" contentplaceholderid="cphContent">
        <asp:UpdatePanel id="updMain" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
                <asp:PlaceHolder id="phMain" runat="server" />
            </ContentTemplate>
        </asp:UpdatePanel>
    </asp:Content>
    

    在导航控制上为所有导航链接执行此操作(更改OnClick以适合要加载的控件 - 这可以在转发器中动态完成):

    <asp:LinkButton id="lbItem" runat="server" onClick="LoadControl1" />
    

    然后在代码隐藏(导航)中你可以:

    protected void LoadControl1(object sender, EventArgs)
    {
        MyControl Con = (MyControl)LoadControl("~/MyControl.ascx");
        ((Default)Page).phMain.Controls.Add(Con);
        ((Default)Page).updMain.Update();
    }
    

    注意,如果没有Master Pages的复杂性,你可以实现同样的目标,但我更喜欢它们。如果你想在没有母版页的情况下这样做,那么你只需默认PlaceHolders并做同样的事情。

    编辑2:

    您也可以使用JQuery()将内容加载到div中。进行页面设置(MasterPage或Normal页面结构)。然后像你这样导航链接:

    <a href="http://www.mysite.com/page1.aspx" class="ajax_link">Link 1</a>
    

    然后有一些Javascript(使用JQuery):

    $(function(){
        $("a.ajax_link").click(function(e){
            ajaxLink(this, e);
        });
    });
    
    function ajaxLink(item, e) {
        var container = $("#ajax_container_wrapper");
        var link;
    
        if (e != null) {
            e.preventDefault();
        }
        link = $(item).attr("href") + " #ajax_container_wrapper"; //Omit the  + " #ajax_container_wrapper"; if you want to drag all the content in.
        container.load(link);
    }
    

    并且:

    <div id="ajax_container_wrapper"></div>
    

    您希望新页面出现在哪里。

    这基本上会将每个链接中指定的新页面加载到div中。

答案 1 :(得分:0)

好吧,也许是迈出了一步 - 你的代码在改变页面的意义上起作用。但据我所知,整个页面仍在重新加载,而不仅仅是我努力做的主要内容领域。

我所做的是我在主页面中提供了javascript代码 - 未经修改的代码。

编辑刚才意识到java函数似乎没有被调用。因此锚点提供“标准”功能,这可能是一个线索:-)如何调用javascript(如下所述,也可以从后面的代码中说明)?我留下这个答案的其余部分只是为了检查其他错误。的 /修改

然后我在左侧导航菜单的底部放置了两个锚点(仍然在母版页中)

<div id="navcol">

    <%-- other left menu stuff --%>

    <a href="../ContentPages/FutureStartPage.aspx" class="ajax_link">Link 1</a>
    <a href="../ContentPages/BusCoachStartPage.aspx" class="ajax_link">Link 2</a>

</div>

我将目标div放在主要内容部分中,也放在母版页中。我还测试了内容持有者内部的div id =“ajax_container_wrapper”和div id =“ajax_container_wrapper”中的contentplaceholder,遗憾的是我没有看到行为上的差异。

<div id="contentcol" runat="server">
    <div id="mpcpholder">
        <asp:ContentPlaceHolder ID="ContentPlaceHolderMainArea" runat="server">
        </asp:ContentPlaceHolder>
    </div>
    <div id="ajax_container_wrapper"></div>
</div>

我也试图省略ContentPlaceHolder但似乎不允许这样做;它给出了一个解析器错误。

所以我可能做错了,但很明显整页都在重新加载,包括顶部和左侧菜单。

也;如果我让它只用于重新加载主要内容区域;我需要从e中做到这一点。 G。树形视图链接,甚至更重要的代码背后。我也很感激有关如何做到这一点的建议。

由于 / DT