angular学习笔记(三十一)-$location(1)

本篇介绍angular中的$location服务的基本用法,下一篇介绍它的复杂的用法.

$location服务的主要作用是用于获取当前url以及改变当前的url,并且存入历史记录.

一. 获取url的相关方法:

以 ‘http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash‘ 这个路径为例:

1. 获取当前完整的url路径:

$location.absUrl():// http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash

*2. 获取当前url路径(当前url#后面的内容,包括参数和哈希值):

$location.url();// /foo?name=bunny#myhash

*3. 获取当前url的子路径(也就是当前url#后面的内容,不包括参数):

$location.path()// /foo

4. 获取当前url的协议(比如http,https)

$location.protocol()// http

5. 获取当前url的主机名

$location.host()// localhost

6. 获取当前url的端口

$location.port()// 80 (这里就是wamp的默认端口号)

*7. 获取当前url的哈希值

$location.hash()// myhash

*8. 获取当前url的参数的序列化json对象

$location.search()// {"name":"bunny"}

二. 修改url的相关方法:

在上面讲到的所有获取url的8个方法,其中*开头的四个方法,可以传入参数进行修改url,在这种情况下,函数的返回值都是$location本身:

1. 修改url的子路径(也就是当前url#后面的内容,不包括参数):

参数格式:字符串

$location.url(‘/foo2?name=bunny2&age=12#myhash2‘);// http://localhost/$location/21.1%20$location.html#/foo2?name=bunny2&age=12#myhash2

2. 修改url的子路径部分(也就是当前url#后面的内容,不包括参数):

参数格式:字符串

$location.path(‘/foo2/foo3‘);// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=bunny2&age=12#myhash2

3. 修改url的哈希值部分

参数格式:字符串

$location.hash(‘myhash3‘);// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=bunny2&age=12#myhash3

4. 修改url的参数部分

(1).传入两个参数,第一个参数的格式为字符串:

①第二个参数的格式也是字符串

第一个参数表示url参数的属性名,第二个参数是该属性名的属性值,如果是已有属性名,则修改,如果不是已有属性,则新增

$location.search(‘name‘,‘code_bunny‘)// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=code_bunny2&age=12#myhash3

②第二个参数的格式为数组,数组中的各个值也是字符串或者布尔值

第一个参数表示url参数的属性名,第二个参数是该属性名的值,有多少个值,url中就会依次重复出现多少个.如下:

$location.search(‘love‘,[‘zxg‘,‘mitu‘])// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=code_bunny2&age=12&love=zxg&love=mitu#myhash3

(2).传入两个参数,第一个参数为字符串,第二个参数为null:

第一个值表示url参数的属性名,如果是已有属性名,则删除该属性,如果不是已有属性,那就等于没改过

$location.search(‘age‘,null)// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=code_bunny2#myhash3

(3).传入一个参数,格式为json对象:

直接用这个json对象里的键值对替换整个url的参数部分

①普通的键值对:

$location.search({name:‘papamibunny‘,age:16,love:‘zxg‘})// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=papamibunny&age=16&love=zxg#myhash3

②属性值为一个数组:(和(1)②一样,重复这个属性)

$location.search({name:[‘code_bunny‘,‘white_bunny‘,‘hua_bunny‘],age:16,love:‘zxg‘})// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=code_bunny&name=white_bunny&name=hua_bunny&age=16&love=zxg#myhash3

(4).传入一个参数,格式为字符串:

直接用这个字符串替换整个url的参数部分(没有键值对,参数部分就是一个属性名,但转换成json对象的话,这个属性的值就是true,但是在url里没有体现)

$location.search(‘bunnybaobao‘)// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?bunnybaobao#myhash3// {"bunnybaobao":true}

三. 不存入历史记录:

在使用 ‘二‘ 里面的所有修改url的方法的时候,每修改一次,url都会被存入历史记录,可以使用后退按钮回到修改前的url,如果不想要这种效果,而仅仅是替换当前的记录,可以使用:

$location.replace()

举个栗子:

// 原url:// http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash
$location.url(‘/foo2?name=bunny2&age=12#myhash2‘);// 修改一次后:// http://localhost/$location/21.1%20$location.html#/foo2?name=bunny2&age=12#myhash2
// 按下后退回到原url:// http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash// 再按下前进回到修改后url:// http://localhost/$location/21.1%20$location.html#/foo2?name=bunny2&age=12#myhash2
$location.path(‘/foo2/foo3‘).replace();// 修改第二次后调用replace():// http://localhost/$location/21.1%20$location.html#/foo2/foo3?name=bunny2&age=12#myhash2
// 按下后退,不会回到第二次修改前的url,而是回到第一次修改前的url:// http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash

四.$locationChangeStart和$locationChangeStart事件

这两个事件分别发生在当url开始发生改变,以及url改变完成.他们都被绑定在$rootScope里面:

    $rootScope.$on(‘$locationChangeStart‘,function(){
        console.log(‘开始改变$location‘)
    });
    $rootScope.$on(‘$locationChangeSuccess‘,function(){
        console.log(‘结束改变$location‘)
    });

这个和$route里的$routeChangeStart和$routeChangeSuccess很类似,但是要注意的是,虽然都是改变url发生的事件,但要触发$locationChangeStart和$locationChangeSuccess事件,就必须是$location服务导致的url变化,通过$route定义导致的url变化,不会触发$locationChangeStart和$locationChangeSuccess事件,同样,这里是通过$location服务导致的url变化,所以即使定义了$routeChangeStart和$routeChangeSuccess事件,它也是不会被触发的.

把上面讲到的这些一起举个栗子:

把 ‘一‘ 里面的8个可以取到的url部分都赋值给$scope里的值,同时,把对应的修改方法绑定在对应的按钮上,以便在视图上查看变化过程.

需要注意的是,这里有个$scope.refresh方法,因为这里$scope下的这些值是不会实时更新的.举栗,$location.url()是个方法,获取当前的url,而不是一个值,所以,当url发生改变以后,不再次调用$location.url(),url值是不可能被实时更新的.所以refresh方法就是在每次url改变完成后,重新获取url对应的部分并更新视图.

html:

<!DOCTYPE html>
<html ng-app="locationApp">
<head>
  <title>21.1 $location</title>
  <meta charset="utf-8">
  <script src="angular.min.js"></script>
  <script src="script.js"></script>
</head>
<body ng-controller="locationCtrl">
  <p>完整url路径: <span>{{absurl}}</span></p>

  <p>url路径(当前url#后面的内容,包括参数和哈希值): <span>{{url}}</span>
    <button ng-click="changeUrl()">改变</button>
  </p>

  <p>相对路径(也就是当前url#后面的内容,不包括参数): <span>{{path}}</span>
    <button ng-click="changePath()">改变</button>
  </p>

  <p>协议(比如http,https): <span>{{protocol}}</span></p>

  <p>主机名: <span>{{host}}</span></p>

  <p>端口号: <span>{{port}}</span></p>

  <p>哈希值: <span>{{hash}}</span>
    <button ng-click="changeHash()">改变</button>
  </p>

  <p>search值序列化json:
    <span>{{search}}</span>
    <button ng-click="changeSearch_1()">改变1</button>
    <button ng-click="changeSearch_2()">改变2</button>
    <button ng-click="changeSearch_3()">改变3</button>
    <button ng-click="changeSearch_4()">改变4</button>
    <button ng-click="changeSearch_5()">改变5</button>
    <button ng-click="changeSearch_6()">改变6</button>
  </p>
</body>
</html>

js:

/*21.1 $location*/
var locationApp = angular.module(‘locationApp‘,[]);
locationApp.controller(‘locationCtrl‘,function($scope,$location,$timeout,$rootScope){
    $scope.absurl = $location.absUrl();
    $scope.url = $location.url();
    $scope.path = $location.path();
    $scope.protocol = $location.protocol();
    $scope.host = $location.host();
    $scope.port = $location.port();
    $scope.hash = $location.hash();
    $scope.search = $location.search();

    $scope.refresh = function(){
        $scope.absurl = $location.absUrl();
        $scope.url = $location.url();
        $scope.path = $location.path();
        $scope.hash = $location.hash();
        $scope.search = $location.search();
    };

    //重写url部分,相应的absurl,url,path,hash,search都会改变
    $scope.changeUrl = function(){
        $location.url(‘/foo2?name=bunny2&age=12#myhash2‘);
    };

    //重写path部分,相应的absurl,url,path都会改变
    $scope.changePath = function(){
        $location.path(‘/foo2/foo3‘);
    };

    //重写hash部分,相应的absurl,url,hash都会改变
    $scope.changeHash = function(){
        $location.hash(‘myhash3‘);
    };

    //修改search部分(方法1),相应的absurl,url,search,hash都会改变
    //指定两个参数,第一个参数是属性名,第二个参数是属性值.
    //如果属性名是已有属性,则修改,如果属性名不是已有的,则新增.
    //属性值也可以是一个数组,参考方法6
    $scope.changeSearch_1 = function(){
        $location.search(‘name‘,‘code_bunny‘);
    };

    //修改search部分(方法2),相应的absurl,url,search,hash都会改变
    //指定两个参数,第二个参数是null:删除第一个参数所指定的属性名.不再有这个属性
    //若第一个参数不是已有的,则不发生任何改变
    $scope.changeSearch_2 = function(){
        $location.search(‘age‘,null);
    };

    //修改search部分(方法3),相应的absurl,url,search,hash都会改变
    //指定一个参数,json对象,直接重写整个search部分.不管是不是已有属性,全部重写.
    //这里属性的值可以是一个数组,参考方法5
    $scope.changeSearch_3 = function(){
        $location.search({name:‘papamibunny‘,age:16,love:‘zxg‘});
    };

    //修改search部分(方法4),相应的absurl,url,search,hash都会改变
    //指定一个参数,字符串,整个search部分就变为这个字符串.注意是没有属性值的.
    $scope.changeSearch_4 = function(){
        $location.search(‘bunnybaobao‘);
    };

    //修改search部分(方法5),相应的absurl,url,search,hash都会改变
    //其余和方法3一样.全部重写search:
    //指定一个参数,json格式,属性值是一个数组,那么最后的search会变成name=code_bunny&name=white_bunny&name=hua_bunny
    $scope.changeSearch_5 = function(){
        $location.search({name:[‘code_bunny‘,‘white_bunny‘,‘hua_bunny‘]});
    };

    //修改search部分(方法6),相应的absurl,url,search,hash都会改变
    //其余和方法1一样,修改指定的属性名(或新增)
    //第二个参数是一个数组,最后search中的love部分会变成love=zxg&love=mitu
    //它和方法5的区别,就像方法1和方法3的区别,一个是修改或新增某个属性值,一个是重置整个search
    $scope.changeSearch_6 = function(){
        $location.search(‘love‘,[‘zxg‘,‘mitu‘]).replace();
    };

    //使用$location.replace(),则这一次的修改路径不会被记录到历史记录中,点击后退,不会后退到改变前的路径,而是后退到改变前的路径的改变前的路径

    $rootScope.$on(‘$locationChangeStart‘,function(){
        console.log(‘开始改变$location‘)
    });
    $rootScope.$on(‘$locationChangeSuccess‘,function(){     $scope.refresh();
        console.log(‘结束改变$location‘)
    });
    //这里就算绑定了$routeChangeStart和$routeChangeSuccess,也不会被触发,因为这里没有$route相关的服务.
});
//注意这里$scope下的这些值是不会实时更新的.举栗url,$location.url()是个方法,获取当前的url,而不是一个值,
//所以,当url发生改变以后,不再次调用$location.url(),url值是不可能被实时更新的.

整个过程如下:

1.初始状态,输入如下url:

http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash

图1.1

依次点击‘改变‘按钮后:

图1.2

----------------------------------------------------------------------------------------------------------------------------

图1.3

----------------------------------------------------------------------------------------------------------------------------

图1.4

----------------------------------------------------------------------------------------------------------------------------

图1.5

----------------------------------------------------------------------------------------------------------------------------

图1.6

----------------------------------------------------------------------------------------------------------------------------

图1.7

----------------------------------------------------------------------------------------------------------------------------

图1.8

----------------------------------------------------------------------------------------------------------------------------

图1.9

----------------------------------------------------------------------------------------------------------------------------

图1.10

此时点击后退,不会回到图1.9,而是回到图1.8

时间: 2024-10-29 19:08:44

angular学习笔记(三十一)-$location(1)的相关文章

angular学习笔记(三十一)-$location(2)

之前已经介绍了$location服务的基本用法:angular学习笔记(三十一)-$location(1). 这篇是上一篇的进阶,介绍$location的配置,兼容各版本浏览器,等. *注意,这里介绍的是基于angular-1.3.2版本的,低版本的$location可能会有问题. hashbang模式和history api创建单页应用 首先,$location是用在单页应用里的...(废话,angular就是用在单页的)...所以,$location处理的是url改变,但是不刷新页面的情况.

angular学习笔记(三十)-指令(5)-link

这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数:scope,iEle,iAttrs,ctrl,linker scope:指令所在的作用域,这个scope和指令定义的scope是一致的.至于指令的scope,会在讲解scope属性的时候详细解释 iEle:指令元素的jqLite封装.(也就是说iEle可以调用angular封装的简版jq的方法和属

angular学习笔记(三十)-指令(6)-transclude()方法(又称linker()方法)-模拟ng-repeat指令

在angular学习笔记(三十)-指令(4)-transclude文章的末尾提到了,如果在指令中需要反复使用被嵌套的那一坨,需要使用transclude()方法. 在angular学习笔记(三十)-指令(5)-link文章也提到了link函数的第五个参数linker. 这篇文章就来讲解一下transclude()方法(linker()方法),是怎么使用的,另外,它也是compile函数的第三个参数,用法一样. 下面就通过自己写一个简易的模拟ngRepeat的指令cbRepeat,来了解linke

angular学习笔记(三十)-指令(7)-compile和link(2)

继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的代码: html: <body> <div ng-controller="compileCtrl"> <level-one> <level-two> <level-three> hello,{{name}} </level-

angular学习笔记(三十)-指令(2)

本篇主要讲解指令中的 restrict属性, replace属性, template属性 这三个属性 一. restrict: 字符串.定义指令在视图中的使用方式,一共有四种使用方式: 1. 元素: E 2. 属性: A 3. 样式类: C 4. 注释: M restrict的值可以是上面四个字母的任意一个或多个的组合. 不指定的话默认为A. 二. replace: 布尔值.是否将指令元素替换,可以有两个值: 1.true: 替换整个使用指令的元素 2.false: 不替换整个使用指令的元素,而

angular学习笔记(三十)-指令(10)-require和controller

本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐directive> <inner‐directive></inner‐directive> </outer‐directive> 这里有两个指令,一个outer-directive指令元素,它里面又有一个inner-directive指令元素. js: app.directiv

angular学习笔记(三十)-指令(1)

之前在 angular学习笔记(十九)-指令修改dom 里面已经简单的提到了angular中的指令,现在来详细的介绍 '指令' 一.指令的创建: dirAppModule.directive('directive-name',function(){ var obj = { restrict:'string', priority:number, template:'string', templateUrl:'string', replace:bool, transclude:bool or str

angular学习笔记(三十)-指令(3)

这篇主要介绍指令中的templateUrl属性: templateUrl属性值是一个url路径,路径指向一个html模板,html模板会填充(或替换)指令内容: 比如上一篇文章里的案例,我们把原来的template属性改用为templateUrl属性: 方法一: html: <!DOCTYPE html> <html ng-app = 'dirAppModule'> <head> <title>20.2 指令(templateUrl)</title&g

angular学习笔记(三十)-指令(8)-scope

本篇讲解指令的scope属性: scope属性值可以有三种: 一.scope:false 默认值,这种情况下,指令的作用域就是指令元素当前所在的作用域. 二.scope:true 创建一个继承了父作用域的子作用域,这样,指令可以访问到父作用域里的值,父作用域的属性值一旦被修改,子作用域里相应的属性值也会被修改,但是子作用域里的属性值修改,不会影响到父作用域里的属性值 举个栗子: html: <!DOCTYPE html> <html ng-app="dirAppModule&q