使用ajax请求更改浏览器URL而不重新加载页面

时间:2014-05-07 15:07:37

标签: javascript jquery ajax codeigniter url

所以我正在学习本教程:

http://www.tinywall.info/2012/02/change-browser-url-without-page-reload-refresh-with-ajax-request-using-javascript-html5-history-api-php-jquery-like-facebook-github-navigation-menu.html

我的目标是加载视图的实际内容并更改浏览器URL而无需重新加载页面。但是,因为我使用CodeIgniter作为我的应用程序的框架,所以我无法让它正常工作。我有一个控制器,我正在加载我的所有Dashboard视图,我希望在我的div中显示一个名为content_container的视图。

问题在于每次我点击另一个锚标记以获得通过ajax请求加载的不同视图时,它会在我的网址中添加另一个“仪表板”,当然它之后不显示视图。因此,点击几次后,URL将如下所示:“dashboard / dashboard / dashboard / profile”。我试图用Javascript分割URL,但这对我没有帮助。

一个解决方案是为每个视图创建单个控制器,但我认为这是一个不好的做法,只需一个控制器来处理所有视图,代码就会更清晰。

这是控制器:

<?php

class Dashboard extends CI_Controller {

    public function __construct()
    {

        parent::__construct();
        $this->output->nocache();
        $this->load->model('subject_model');
        $this->load->model('user_model');
    }


    public function index()
    {

        $this->load->view('header');
        $this->load->view('dashboard');
        $this->load->view('footer');
    }

    public function users() 
    {

        $data['users'] = $this->user_model->getUsers();
        $this->load->view('staff_users', $data);
    }
    public function lomake()
    {

        $this->load->view('lomake');
    }

    public function profile()
    {

        $data['userinfo'] = $this->user_model->getUserInformationById($this->session->userdata('user_id'));
        $this->load->view('myprofile', $data);
    }

    public function subjects()
    {

        $this->load->view('subjects');
    }   
}
?>

这是我的仪表板视图(部分内容):

<aside id="left_control_panel">

    <ul id="left_control_links">
        <li>
        <a href="home" id="ajax" class="active">Home</a>
        </li>
        <li>
        <a href="dashboard/subjects" rel="tab">Subjects</a>
        <span class="list_total_count"><?=$total_subjects?></span>
        </li>

        <li>
        <a href="dashboard/lomake" id="ajax">Query</a>
        </li>

    <?php if($this->session->userdata('user_type') == 'admin'):?>

        <span class="left_control_heading">User management</span>
        <li>
        <a href="dashboard/users" rel="tab">Users</a>
        <span class="list_total_count"><?=$total_users?></span>
        </li>

        <li>
        <a class="add_user" href="add_user">Add User</a>
        </li>
    <?php endif;?>

        <span class="left_control_heading">Account management</span>
        <li>
        <a href="dashboard/profile" rel="tab">My Profile</a>
        </li>

        <li>
        <a href="<?=base_url()?>users/logout">Sign Out</a>
        </li>
    </ul>
</aside> <!-- end of left_control_panel -->

<div id="wrapper_loggedin">
        <div class="content_container">
        <! -- I will display all the data from different views in here -->
        </div>
</div> <!-- end of wrapper_loggedin -->

最后JS部分也可以在教程中找到:

$(function(){
    $("a[rel='tab']").click(function(e){
        //e.preventDefault(); 
        pageurl = $(this).attr('href');

        $.ajax({url:pageurl+'?rel=tab',success: function(data){
            $('.content_container').html(data);
        }});

        //to change the browser URL to 'pageurl'
        if(pageurl!=window.location){
            window.history.pushState({path:pageurl},'',pageurl);    
        }
        return false;  
    });
});

/* the below code is to override back button to get the ajax content without reload*/
$(window).bind('popstate', function() {
    $.ajax({url:location.pathname+'?rel=tab',success: function(data){
        $('.content_container').html(data);
    }});
});

应用/配置/ routes.php文件

$route['dashboard'] = 'dashboard/index';

$route['dashboard/(:any)'] = 'dashboard/$1';

4 个答案:

答案 0 :(得分:1)

嗯,根据我的具体情况,我有数千种产品按类别和子类别组织。嗯..大量的网址和控制器写。所以我所做的是制作一个类别模板,一个子类别模板和一个产品页面模板。然后在我的application / config / routes.php文件中创建如下所示的路由:

$route['products'] = 'products/index';

//so i know now they are on a category page and $1 is the name of the category.
//i can go query my db and get all subcategorys and the products under each now.
$route['products/(:any)'] = 'products/category/$1'; 

//the 1 and 2 here are category and subcategory from the url. so i know from this to
//use these in my query to grab all products in this category and subcategory.
$route['products/(:any)/(:any)'] = 'products/subcategory/$1/$2'; 

//i know this is gonna be a product page. and i know the category, the sub category and the product name. in this case all i really need is the product name since there is only one product with that name.
$route['products/(:any)/(:any)/(:any)'] = 'products/details/$1/$2/$3';

在你的情况下你也可以这样做。使用你的网址,你花时间建立它们,所以使用它们。在javascript中,您可以通过'window.location.pathname'将它们发送回您的控制器;所有你需要做的就是分开它,你可以使用相同的心态来加载页面并确切地知道你在哪里。

另外,在你的ajax url属性中,确保你的url是一个绝对url,或者它首先引用root。我想我知道你的问题是什么。你在你的url属性中使用了像“users / dashboard”这样的url,当它应该是“/ users / dashboard”时你需要总是去root并获取控制器,否则它会使用url并且总是采用“用户/仪表板“到你当前的网址。因此,如果你在“用户/仪表板”并再次加载它,你实际上告诉它加载“/ users / dashboard / users / dashboard”,这就变成了一个无限循环。只需在您的网址前加一个反斜杠,它就会始终引用根。

答案 1 :(得分:0)

我刚刚做了同样的事情。我这样做的方法是首先制作一个动态路线,始终指向同一个控制器。 $ route [&#39; products /(:any)/(:any)/(:any)&#39;] =&#39;产品/详情/ $ 1 / $ 2 / $ 3&#39 ;;然后,只要你的网页通过网址加载(如果有人放入特定的网址),你仍然可以获得内容(书签仍然有效,你可以向人们发送特定的网址等)。然后,我所做的是每个更改内容的链接也应用了一个数据属性来构建url,我也会使用那些传递给同一个控制器。该控制器还会检查请求是否来自ajax请求...如果是,您只需加载页面内容......如果不是,则加载完整模板。它真的不那么难,你实际上几乎拥有我拥有的东西。我想你是在考虑它。但我要做的第一件事就是确保首先使用url工作每个页面。然后尝试让ajax部分工作。关键是检测请求是否来自控制器中的ajax。然后你可以区分这两者。

答案 2 :(得分:0)

此外,我强烈建议您阅读用户指南。当您开始使用Codeigniter构建项目时,这些路径通常是您应该首先考虑的事项之一。

http://ellislab.com/codeigniter/user-guide/general/routing.html

答案 3 :(得分:0)

在核心控制器上回答您的问题。答案是肯定的,您在核心文件夹中创建了一个控制器。它必须有一个特定的名称。在您的application / config / config.php文件中,您应该:

$config['subclass_prefix'] = 'MY_';

这定义了任何扩展核心控制器,模型或系统类的前缀。大多数Codeigniter系统类都可以扩展,您可以覆盖属性(变量)和方法(函数)。在您的情况下,您将在应用程序/核心文件夹中删除名为MY_Controller.php的文件。在这个控制器中,你可以像你编写的任何其他控制器一样接近它,不必一遍又一遍地重写相同的代码,或改变默认控制器的运行方式。您应该了解php类如何工作以及使用它们的目的。 Codeigniter并没有像你想要的那样使用它们,但是他们用MVC方法接近它。通常,类被引用为对象。把班级想象成一个熊。熊有重量,年龄,长度,颜色,高度。所有这些都被称为&#34;属性&#34;。熊也可以吃,喝,狩猎。这些中的每一种都被称为&#34;方法&#34;。熊的更详细版本将是北极熊,可怕熊或熊猫熊。这些可能是熊对象的子节点(它们会扩展Bear对象)。任何子对象都继承其父属性和方法。但他们的价值观和行动可能不同。北极熊的颜色,大小,高度与熊猫不同,但仍然可以吃,喝,狩猎。某些属性和方法可能不会更改,因此没有理由重写子类中的那些属性和方法。因此,在您的情况下,核心控制器可以处理每个页面所做的事情。它可以验证会话,跟踪用户活动,定义全局错误消息等。甚至在我的核心控制器中创建一个方法,将我的模板片段加载到一起(页眉,页脚,侧边栏,内容),所以我没有&#39 ;当我加载我的模板时,我必须继续堆叠$ this-&gt; load-&gt; view()。我所要做的就是传递需要传递的内容和数据,并在任何地方加载我的模板。您还需要了解__construct的工作原理。您可以将__construct视为在页面加载之前始终首先运行的函数。因此,通过在核心控制器中定义构造,您可以自动填充数据。浏览这些链接,因为他们会深入解释如何使用这些功能并显示示例。

http://ellislab.com/codeigniter/user-guide/general/core_classes.html

http://www.php.net/manual/en/language.oop5.php

如果这引导了你正确的方向,请给我一个投票:)我试图建立我的积分和个人资料,并最终将我的帐户链接到我的网站,所以它证明我的过多的PHP&amp;为任何未来的员工提供代码签名知识。