dongwupu5991
dongwupu5991
2014-09-14 13:19

Angular将主视图呈现两次,而不是加载正确的模板

I'm having a problem with Angular templating - instead of including the correct template, the main view (view that initially gets loaded) is renderend twice. After spending the most of the last 2 days trying to solve this, I'm still getting nowhere.

More detailed description:

I'm using Angular to develop a single page application for managing a website's content. The rest of this website is built with Laravel. Angular is used only for the content management system which is a separate application that's protected by Laravel's HTTP filters and authentication system.

The problem occurs when the Angular app is not located at the root URL (for example, http://application.dev works, while http://application.dev/admin doesn't).

The main code (stripped down to essentials in an attempt to find the problem):

/*global angular*/
var App = angular.module('Dashboard', ['ui.router']);

App.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
    'use strict';
    $locationProvider.html5Mode(true).hashPrefix('!');

    $stateProvider.state('statistics', {
        url: '/statistics',
        templateUrl: 'statistics/index.html'
    });

    $stateProvider.state('notifications', {
        url: '/notifications',
        templateUrl: 'notifications/index.html'
    });

    $urlRouterProvider.when('/', '/statistics');
});

The application view:

<!DOCTYPE html>
<html lang="en" ng-app="Dashboard">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <base href="/admin/">
    </head>
    <body>
        <div id="container" class="full">
            <header>
                <nav>
                    <ul>
                        <li><a ui-sref="statistics">Statistics</a></li>
                        <li><a ui-sref="notifications">Notifications</a></li>
                    </ul>
                </nav>
            </header>
            <div id="content" ui-view></div>
        </div>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.24/angular.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
        <?php echo HTML::script(asset('javascripts/main.js')) ?>
    </body>
</html>

Sample template that doesn't get included for some reason:

<section id="statistics">
    <h3>Statistics</h3>
</section>

Laravel routing file:

Route::group(
    [
        'namespace' => 'Admin',
        'prefix' => 'admin'
    ],
    function () {
        Route::group(
            [
                'namespace' => 'Account'
            ],
            function () {
                Route::group(
                    [
                        'prefix' => 'login'
                    ],
                    function () {
                        Route::get('/', [
                            'as' => 'admin.login',
                            'uses' => 'LoginController@showLogin'
                        ]);

                        Route::post('/', [
                            'uses' => 'LoginController@attemptLogin'
                        ]);
                    }
                );

                Route::get('logout', [
                    'as' => 'admin.logout',
                    'uses' => 'LogoutController@attemptLogout'
                ]);
            }
        );

        Route::get('/', [
            'as' => 'admin.dashboard',
            'before' => 'auth',
            'uses' => 'DashboardController@start'
        ]);
    }
);

Every time I'm using the templateUrl option (template obviously works since no file is included), it doesn't include the correct template. Instead another request is fired to http://application.dev/admin URL and it essentially duplicates the whole view after receiving the 200 OK status code. I've tried to narrow the problem using Chrome's developer tools - the only unusual thing was that the requests initiator is the template (or URL) that should be included normally. Unfortunately that doesn't help much.

I'm a bit suspicious that the problem might be caused by Laravel's routing or URL rewriting, but I haven't been enable to verify it yet. Any ideas what could be the reason of this behaviour?

Edit:

Added the routes.php file in case it might be causing this problem.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • dongyikong6207 dongyikong6207 7年前

    After spending too much time on this, I finally found out what the problem was. As it turns out, when URL is multiple sections deep (like in my situation), a forward slash has to be prepended to the templateUrl value. In my case it had to be something like this: /javascripts/statistics/index.html.

    Seems such a simple solution, but it caused me too much headache. I'm posting this in case anyone encounters a similar problem.

    The credit goes to this answer.

    点赞 评论 复制链接分享