在路由中使用.run时从Angularjs中的URL中删除#

时间:2015-11-30 11:27:40

标签: javascript php angularjs laravel angularjs-directive

这是我在AngularJS中的app.js路由文件

var app = angular.module('myApp', ['ngRoute', 'ngAnimate', 'toaster']);
app.config(['$routeProvider',
    function ($routeProvider) {
        $routeProvider.
                when('/login', {
                    title: 'Login',
                    templateUrl: 'resources/views/layouts/loginUser.php',
                    controller: 'authCtrl'
                })
                .when('/', {
                    title: 'Login',
                    templateUrl: 'resources/views/layout/login.php',
                    controller: 'logoutCtrl'
                })
                .when('/reset', {
                    title: 'Reset Password',
                    templateUrl: 'resources/views/layouts/forgetPassword.php',
                    controller: 'authCtrl'
                })
                .when('/invalidtoken', {
                    title: 'Login',
                    templateUrl: 'resources/views/layout/invalidtoken.php',
                    controller: 'authCtrl',
                    role: '0'
                })

                //$locationProvider.html5Mode(true);
    }])


        .run(function ($rootScope, $location, Data, $http) {
            $rootScope.$on("$routeChangeStart", function (event, next, current) {
                     var nextUrl = next.$$route.originalPath;

                    if (nextUrl == '/signin' || nextUrl == '/login' || nextUrl == '/verify' || nextUrl == '/register' || nextUrl == '/registered' || nextUrl == '/reset' || nextUrl == '/resetdone' || nextUrl == '/registersuccess')
                    {
                        $location.path(nextUrl);
                    }
                     else
                    {   

                        $location.path('/');
                    }      
            });
        });

这里我用.run来处理很少的请求。

我想从网址中删除#以使网址漂亮,

所以我这样做是为了删除建议的here

app.config(['$routeProvider', '$locationProvider'
    function ($routeProvider, $locationProvider) {

并在最后一行

$locationProvider.html5Mode(true);

但是应用程序没有发生任何事情,它仍然在网址中有#。

即使我尝试this方式

我怎样才能做到这一点?

更新:

如果我这样做

.run(function ($rootScope, $location, Data, $http, $locationProvider) {

并在最后一行

$locationProvider.html5Mode(true);

我收到此错误

Error: $injector:unpr
Unknown Provider

我曾尝试过多种方式,但都没有。

更新2:

或者任何人都可以建议一个angularjs示例的链接,该示例在url中提供没有#的示例?

7 个答案:

答案 0 :(得分:5)

为什么要使用.run()?将<base href="/" />添加到<head>或从您的身体开始(第一行)然后匹配.run()的逻辑尝试此操作(.otherwise("/path")到您的$routeProvider) :

var app = angular.module('myApp', ['ngRoute', 'ngAnimate', 'toaster']);
app.config(['$routeProvider', '$locationProvider',
    function ($routeProvider, $locationProvider) {
        $routeProvider.
                when('/login', {
                    title: 'Login',
                    templateUrl: 'resources/views/layouts/loginUser.php',
                    controller: 'authCtrl'
                })
                .when('/', {
                    title: 'Login',
                    templateUrl: 'resources/views/layout/login.php',
                    controller: 'logoutCtrl'
                })
                .when('/reset', {
                    title: 'Reset Password',
                    templateUrl: 'resources/views/layouts/forgetPassword.php',
                    controller: 'authCtrl'
                })
                .when('/invalidtoken', {
                    title: 'Login',
                    templateUrl: 'resources/views/layout/invalidtoken.php',
                    controller: 'authCtrl',
                    role: '0'
                })
. otherwise("/");
           $locationProvider.html5Mode(true);
    }]);

如果您仍然遇到问题,我建议https://github.com/angular-ui/ui-router

<强>更新

您的index.html

<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>Green Hopping</title>
        <link rel="shotcut icon" type="favicon.ico" href="public/images/favicon.ico" />
        <link rel="icon" type="favicon.ico" href="public/images/favicon.ico" />
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
        <script src="https://code.angularjs.org/1.4.2/angular-route.min.js"></script>

    </head>
    <body ng-cloak="">
      <base href="/">
        <div data-ng-view="" id="ng-view" class="slide-animation"></div>
    </body>

    <script>
      var app = angular.module('myApp', ['ngRoute']);
        app.config(['$routeProvider', '$locationProvider',
            function ($routeProvider, $locationProvider) {
                $routeProvider.
                        when('/', {
                            title: 'Home',
                            templateUrl: 'home.html',
                            controller: 'homeCtrl'
                        })
                        .when('/login', {
                            title: 'Login',
                            templateUrl: 'login.html',
                            controller: 'authCtrl'
                        })
                        .when('/logout', {
                            title: 'Logout',
                            templateUrl: 'logout.html',
                            controller: 'logoutCtrl'
                        })
                        .when('/dashboard', {
                            title: 'Dashboard',
                            templateUrl: 'dashboard.html',
                            controller: 'dashboardCtrl'
                        })          
                        .otherwise('/');              
                        $locationProvider.html5Mode(true);
            }])
        .run(function ($rootScope, $location, $http, loginSrv) {
            $rootScope.$on("$routeChangeStart", function (event, next, current) {
                    var nextUrl = next.$$route.originalPath;
                    var orUseUrl = $location.path();
                    console.log(nextUrl);
                    if (nextUrl === '/logout'){loginSrv.logout();}
                    if (nextUrl === '/login'){loginSrv.login();}
                    if (loginSrv.loggedin === false) { $location.path('/'); } 
                    else { $location.path(nextUrl); }
            });
        });
        app.service("loginSrv",function(){
          var ls= this;
          ls.loggedin = false;
          ls.logout = function(){
            ls.loggedin = false;
          }
          ls.login = function(){
            ls.loggedin = true;
          }
        });
        app.controller("homeCtrl",function($scope, loginSrv){
          $scope.loggedin = loginSrv.loggedin;
        })     
        app.controller("dashboardCtrl",function($scope, loginSrv){
          $scope.loggedin = loginSrv.loggedin;
        })                    
        app.controller("authCtrl",function($scope, loginSrv){
          $scope.loggedin = loginSrv.loggedin;
        })
        app.controller("logoutCtrl",function($scope, loginSrv){
          $scope.loggedin = loginSrv.loggedin;
        })        
    </script>

</html>

所有其他模板都是这样的。复制粘贴home.htmllogin.htmldashboard.htmllogout.html的以下内容。 Plunker将无法显示客户端路线的问题。试试这个。这是完全功能的代码。

<div>
    <div><a href="/">Home</a> | 
    <a href="/login">Login</a> | 
    <a href="/dashboard">Dashboard</a> | 
    <a href="/logout">Logout</a></div>

    <div> This is from the home/login/dashboard/logout Controller. Loggedin: {{loggedin}}</div>
</div>

答案 1 :(得分:2)

尝试改变:

$locationProvider.html5Mode(true);

致:

$locationProvider.html5Mode({
   enabled: true,
   requireBase: false
});

答案 2 :(得分:0)

您是否偶然收到404错误?每当您将模式更改为html5history时,无论请求的URL是什么,您都必须告诉Web服务器始终返回索引页。正如角度文档在这里所说: https://docs.angularjs.org/guide/ $位置

  

使用此模式需要在服务器端重写URL,基本上您必须重写所有指向应用程序入口点的链接(例如index.html)。要求<base>标签对于这种情况也很重要,因为它允许Angular区分作为应用程序库的url部分和应用程序应该处理的路径。

您是否尝试过并正确配置? 还要记住,您必须指定应用程序的基本条目href才能使其像

一样工作
  <base href="/" />

答案 3 :(得分:0)

您无法在$locationProvider中注入.run,因为提供商仅适用于.config

This answer should help但您将遇到两个问题:

  1. 您需要在$locationProvider.html5Mode(true)之前进行检查,因为它不适用于IE 10或更早版本。

    if(window.history && window.history.pushState){
        $locationProvider.html5Mode(true);
    } 
    
  2. 只有当用户在网址中输入#时才会删除此功能,即如果用户输入app/#/login,它将更改为app/login。但是,如果用户书签或复制更改的网址app/login并在浏览器中输入,则会收到错误,因为服务器不知道角度路由,因为它只是客户端。在我上面链接的主题中,您可能会找到一些关于如何解决这个问题的评论。

答案 4 :(得分:0)

问题是缺少服务注入。 所以在配置部分尝试注入$ locationProvider,如下所示。

app.config(['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
    $routeProvider.
            when('/login', {
                title: 'Login',
                templateUrl: 'resources/views/layouts/loginUser.php',
                controller: 'authCtrl'
            })
            .when('/', {
                title: 'Login',
                templateUrl: 'resources/views/layout/login.php',
                controller: 'logoutCtrl'
            })
            .when('/reset', {
                title: 'Reset Password',
                templateUrl: 'resources/views/layouts/forgetPassword.php',
                controller: 'authCtrl'
            })
            .when('/invalidtoken', {
                title: 'Login',
                templateUrl: 'resources/views/layout/invalidtoken.php',
                controller: 'authCtrl',
                role: '0'
            })

            $locationProvider.html5Mode(true);
}])

答案 5 :(得分:0)

使用html5mode,您必须在html文件中指定基本URL,例如

apply plugin: 'com.android.application'

android {
compileSdkVersion "Google Inc.:Google APIs:23"
buildToolsVersion "23.0.1"    

defaultConfig {
    applicationId "com.wasptech.intellidroid"
    minSdkVersion 13
    versionCode 388
    targetSdkVersion 22
    versionName "2.38.08 - RC2"
    multiDexEnabled true       
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_7
    targetCompatibility JavaVersion.VERSION_1_7
}

dexOptions {
    incremental true
    javaMaxHeapSize "4g"
}

buildTypes {
    release {
        //minifyEnabled true
        signingConfig signingConfigs.release
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
compile 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'

compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.android.gms:play-services:8.1.0'

compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:support-v13:23.1.1'

compile 'com.crittercism:crittercism-android-agent:5.3.3'

compile 'com.google.code.gson:gson:2.3'
compile 'com.squareup.retrofit:retrofit:1.7.1'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'
compile 'com.squareup.okhttp:okhttp:2.0.0'
compile 'com.squareup.okio:okio:1.0.0'
compile 'com.squareup:otto:1.3.5'
compile 'com.github.lecho:hellocharts-library:1.5.0@aar'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3'

compile 'com.squareup.picasso:picasso:2.5.2'

compile 'com.jakewharton.timber:timber:3.1.0'

compile 'com.github.PhilJay:MPAndroidChart:v2.0.7'

compile 'org.osmdroid:osmdroid-android:4.3'
compile 'org.slf4j:slf4j-simple:1.6.1'

compile project(':mobihelp_sdk_android_v1.4')
compile files('libs/osmbonuspack_v5.1.jar')

compile files('libs/espresso-1.1-bundled.jar')

compile 'com.android.support.test.espresso:espresso-core:2.2'
compile 'com.android.support.test:runner:0.3'
}

您可以查看一些链接供您参考,

https://docs.angularjs.org/error/ $位置/ nobase将

https://scotch.io/quick-tips/pretty-urls-in-angularjs-removing-the-hashtag

答案 6 :(得分:0)

你不可能手动从href中删除hash-bang(#),并且它会导致路由器出现故障,因为hashbangs使浏览器不会处理你的状态以便将get请求发送到终点。除非您在html5模式下使用您的网址提供程序,否则浏览器在进行/路由时不会通过#/ route触发get请求。对于html5模式,请将以下行添加到app.config函数中:

$locationProvider.html5Mode(true).hashPrefix('!')