Angularjs   发布时间:2022-04-20  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了AngularJS $location学习笔记大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

AngularJS $LOCATIOn学习笔记

一、$lacation能做什么?

@H_403_5@  $LOCATIOn服务分析浏览器地址栏中的URL(基于window.LOCATIOn),让我们可以在应用中较为方便地使用URL里面的东东。在地址栏中更改URL,会响应到$LOCATIOn服务中,而在$LOCATIOn中@L_673_1@URL,也会响应到地址栏中。
1. $LOCATIOnProvider:
1. 暴露当前浏览器地址栏的URL,所以我们可以注意和观察URL
2. 改变URL,当用户做以下操作时,与浏览器一起同步URL:
改变地址栏
单击后退或者前进按钮(或者点击一个历史链接)。
单击一个链接
将uRL对象描绘为一系列的方法(protocol,host,path,search,hash)。
1. 比较$LOCATIOn和window.LOCATIOn
  1) 目的:window.LOCATIOn和$LOCATIOn服务,都允许对当前浏览器的LOCATIOn进行读写访问。
  2) API:window.LOCATIOn暴露一个未经加工的对象,附带一些可以直接@L_673_1@的属性;而$LOCATIOn服务则是暴露一些jQuery风格的getter/setter方法
  3) 与angular应用声明周期的整合:$LOCATIOn知道关于所有内部声明周期的阶段,与$watch等整合;而window.LOCATIOn则不行。
  4) 与HTML5 API无缝结合:是(with a fallBACk for legacy browsers,对于低版本的浏览器有兼容手段?);而window.LOCATIOn则没有。
  5) 知道应用加载的文档根目录(docroot)或者上下文(context):window.LOCATIOn不行,wnidow.LOCATIOn.path会返回”/docroot/子路径”;而$LOCATIOn.path()返回真实的docroot。
2. 什么时候应该用 $LOCATIOn?
  在应用中,任何需要对当前URL的改变作出响应,或者想去改变当前浏览器的URL的时候。
3. 什么时候不应该用?
当浏览器URL改变的时候,不会导致页面重新加载(page reload)。如果需要做这件事情(更改地址,实现pagereload),请使用较低级别的API,$window.LOCATIOn.href。

二、General overview of the API(API的总体概述)

@H_403_5@  $LOCATIOn 服务可以根据它初始化时的配置而有不同的表现。认配置是适合大多数应用的,其他配置定制,可以开启一些新特性。
  当$LOCATIOn服务初始化完毕,我们可以以jQuery风格的getter、setter方法来使用它,允许我们获得或者改变当前浏览器的URl。

  1. @H_403_5@配置$LOCATIOn服务
    想配置$LOCATIOn服务,需要获得$LOCATIOnProvider,并设置以下参数:
    html5Mode(modE){Boolean},true - see HTML5 mode;false - see Hashbang mode,认: false。
    hashPrefix(prefiX):{String},hashbang使用的前缀(html5Mode为false时,使用hashbang mode,以适应不支持HTML5 mode的浏览器),认:’!’

  2. @H_403_5@Getter and setter method
      $LOCATIOn 服务为只读的URL部分(absUrl,protocol,host,port)提供getter方法,也提供url,path,search,hash的getter、setter方法

// get the current path
    $LOCATIOn.path();

    // change the path
    $LOCATIOn.path('/newValue')
@H_403_5@  所有setter方法都返回同一个$LOCATIOn对象,以实现链式语法。例如,在一句里面@L_673_1@多个属性,链式setter方法类似:
  `
  $LOCATIOn.path(‘/newValue’).search({key:value});
  

  有一个特别的replace方法,可以用作告诉$LOCATIOn服务,在下一次与浏览器同步时,使用某个路径代替最新的历史记录,而不是创建一个新的历史记录。当我们想实现重定向(redirection)而又不想使后退按钮(后退按钮回重新触发重定向)失效时,replace方法就很有用了。想改变当前URL而不创建新的历史记录的话,我们可以这样做:

$LOCATIOn.path(‘/someNewPath’).replace();
@H_403_5@  注意,setter方法不会马上更新window.LOCATIOn。相反,$LOCATIOn服务会知道scope生命周期以及合并多个$LOCATIOn变化为一个,并在scope的$digest阶段一并提交到window.LOCATIOn对象中。正因为$LOCATIOn多个状态的变化会合并为一个变化,到浏览器中,只调用一次replace()方法,让整个commit只有一个replace(),这样不会使浏览器创建额外的历史记录。一旦浏览器更新了,$LOCATIOn服务会通过replace()方法重置标志位,将来的变化将会创建一个新的历史记录,除非replace()被再次调用

@H_403_5@Setter and character encoding
  我们可以传入特殊字符到$LOCATIOn服务中,服务会按照RFC3986标准,自动对它们进行编码。当我们访问这些方法时:
所有传入$LOCATIOn的setter方法的值,path()、search()、hash(),都会被编码。
getter方法(没参数)返回的值都是经过解码的,如path(),search(),hash()。
当我们调用absUrl()方法时,返回的值是包含已编码部分的完整url。
当我们调用url()方法时,返回的是包含path、search和hash部分的已经编码的url,如/path?search=1&b=c#hash。

@H_403_5@三、Hashbang and HTML5 Modes

@H_403_5@$LOCATIOn服务有两个配置模式,可以控制浏览器地址栏的URL格式:Hashbang mode(认)与基于使用HTML5 History API的HTML5 mode。在两种模式下,应用都使用相同的API,$LOCATIOn服务会与正确的URL片段、浏览器API一起协作,帮助我们进行浏览器URL变更以及历史管理。

@H_403_5@

  1. Hashbang mode (default modE)
      在这个模式中,$LOCATIOn在所有浏览器中都使用Hashbang URL。查看下面的代码片段,可以了解更多:
it('should show example',inject(
    function($LOCATIOnProvider) {
        $LOCATIOnProvider.html5mode = false;
        $LOCATIOnProvider.hashPrefix = '!';
    },function($LOCATIOn) {
    // open http://host.com/base/index.html#!/a
    $LOCATIOn.absUrl() == 'http://host.com/base/index.html#!/a';
    $LOCATIOn.path() == '/a';
    $LOCATIOn.path('/foo');
    $LOCATIOn.absUrl() == 'http://host.com/base/index.html#!/foo';
    $LOCATIOn.search() == {};//search没东东的时候,返回空对象
    $LOCATIOn.search({a: 'b',c: true});
    $LOCATIOn.absUrl() == 'http://host.com/base/index.html#!/foo?a=b&c';
    $LOCATIOn.path('/new').search('x=y');//可以用字符串的方式更改search,每次设置search,都会覆盖之前的search
    $LOCATIOn.absUrl() == 'http://host.com/base/index.html#!/new?x=y';
    }
));
@H_403_5@  Crawling your app(让google能够对@R_814_9616@进行索引)
  如果我们想让我们的Ajax应用能够被索引,我们需要在head中增加一个特殊的@L_618_64@标签

@H_403_5@
  这样做,将让爬虫机器人使用escaped_fragment参数请求当前的链接,让我们的服务器认识爬虫机器人,并提供对应的HTML快照。想了解更多关于这个技术的信息,可以查看https://developers.google.com/webmasters/ajax-crawling/docs/specification?hl=zh-CN

四、HTML5 mode

@H_403_5@  在HTML5模式中,$LOCATIOn服务的getter、setter通过HTML5的History API与浏览器URL进行交互,允许使用正规的path、search模块,代替hashbang的模式。如果部分浏览器不支持HTML5 History API,$LOCATIOn服务会自动退回到使用hashbang URL的模式。为了让我们能够从不清楚显示@R_814_9616@的浏览器是否支持history API的担心中解脱出来,使用$LOCATIOn服务是一个正确的、最佳的选择。
  在旧版浏览器中打开一个正规的URL会转换为hashbangURL。
  在现代浏览器中打开一个hashbangURL,会重写为一个正规的URL。
1. 向前兼容旧版浏览器
对于支持HTML5 history API 的浏览器,$LOCATIOn回使用它们去写path和search。如果浏览器不支持history API,$LOCATIOn会转为提供Hashbang URL。这是$LOCATIOn服务自动转换的。

  1. HTML link rewriTing
    当我们使用historyAPImode的时候,我们对于不同的浏览器,需要不同的链接,但我们只需要提供正规的URL即可,例如link
    用户单击这个超链接时:
    在旧的浏览器中,URL会改为/index.html#!/some?foo=bar
    在现代浏览器中,URL会改为/some?foo=bar在下面的情况中,链接不会被重写,而是会使页面加载到对应Url中:
    包含target的超链接link
    到不同domain的绝对链接link
    设置了base路径后,通过” /”开头的链接到不同base路径的超链接link
  2. server side
    使用这个方式,在服务端请求URL重定向,通常,我们需要重定向我们所有的链接到@R_814_9616@中。(例如index.html)。
  3. Relative links
    确保检查所有相链接图片、脚本等。我们必须在中指定base url(),并在所有地方使用绝对url(以/开头)。因为相对URL会根据document的初始路径(通常与应用的root有所不同),转化为绝对url。(relative urls will be resolved to absolute urls using the initial absolute url of the document,which is often different from the root of the application)。我们十分鼓励在document root中运行允许使用History API的angular应用,因为这很好地照顾到相对链接的问题。
  4. 例子
    下面的例子中可以看到两个 $LOCATIOn实例,两个都是html5 mode,但在不同的浏览器上,所以我们可以看到两者之间的不同点。这些$LOCATIOn服务与两个假的“浏览器”连接。每一个input代表浏览器的地址栏。
    注意,当我们输入hashbang地址到第一个“浏览器”(或者第二个?),它不会重写或重定向另外的Url,这个转换过程只会发生在page reload的时候。@H_675_253@
<!DOCTYPE html> <html ng-app> <head> <base href=""/> <@L_618_64@ http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>fake-browser</title> <@L_618_64@ content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"> <style type="text/css"> .ng-cloak { display: none; } </style> </head> <body> <div ng-non-bindable class="html5-hashbang-example"> <div id="html5-mode" ng-controller="Html5Cntl"> <h4>Browser with History API</h4> <div ng-address-bar browser="html5"></div><br><br> $LOCATIOn.protocol() = {{$LOCATIOn.protocol()}}<br> $LOCATIOn.host() = {{$LOCATIOn.host()}}<br> $LOCATIOn.port() = {{$LOCATIOn.port()}}<br> $LOCATIOn.path() = {{$LOCATIOn.path()}}<br> $LOCATIOn.search() = {{$LOCATIOn.search()}}<br> $LOCATIOn.hash() = {{$LOCATIOn.hash()}}<br> <a href="http://www.host.com/base/first?a=b">/base/first?a=b</a> | <a href="http://www.host.com/base/sec/ond?flag#hash">sec/ond?flag#hash</a> | <a href="/other-base/another?search">external</a> </div> <div id="hashbang-mode" ng-controller="HashbangCntl"> <h4>Browser without History API</h4> <div ng-address-bar browser="hashbang"></div><br><br> $LOCATIOn.protocol() = {{$LOCATIOn.protocol()}}<br> $LOCATIOn.host() = {{$LOCATIOn.host()}}<br> $LOCATIOn.port() = {{$LOCATIOn.port()}}<br> $LOCATIOn.path() = {{$LOCATIOn.path()}}<br> $LOCATIOn.search() = {{$LOCATIOn.search()}}<br> $LOCATIOn.hash() = {{$LOCATIOn.hash()}}<br> <a href="http://www.host.com/base/first?a=b">/base/first?a=b</a> | <a href="http://www.host.com/base/sec/ond?flag#hash">sec/ond?flag#hash</a> | <a href="/other-base/another?search">external</a> </div> </div> <script src="../angular.js" type="text/javascript"></script> <script type="text/javascript"> function FakeBrowser(initUrl,baseHref) { this.onUrlChange = function(fn) { this.urlChange = fn; }; this.url = function() { return initUrl; }; this.defer = function(fn,delay) { setTimeout(function() { fn(); },delay || 0); }; this.baseHref = function() { return baseHref; }; this.notifyWhenOutstandingrequests = angular.noop; } var browsers = { html5: new FakeBrowser('http://www.host.com/base/path?a=b#h','/base/index.html'),hashbang: new FakeBrowser('http://www.host.com/base/index.html#!/path?a=b#h','/base/index.html') }; function Html5Cntl($scope,$LOCATIOn) { $scope.$LOCATIOn = $LOCATIOn; } function HashbangCntl($scope,$LOCATIOn) { $scope.$LOCATIOn = $LOCATIOn; } function initEnv(Name) { var root = angular.element(document.getElementById(name + '-mode')); angular.bootstrap(root,[ function ($compileProvider,$LOCATIOnProvider,$providE) { debugger; $LOCATIOnProvider.html5Mode(true).hashPrefix('!'); $provide.value('$browser',browsers[name]); $provide.value('$document',root); $provide.value('$sniffer',{history:name == 'html5'}); $compileProvider.directive('ngAddressBar',function () { return function (scope,elm,attrs) { var browser = browsers[attrs.browser],input = angular.element('<input type="text" style="width:400px;">').val(browser.url()),delay; input.bind('keypress keyup keydown',function () { if (!delay) { delay = setTimeout(fireUrlChange,250); } }); browser.url = function (url) { return input.val(url); }; elm.append('Address: ').append(input); function fireUrlChange() { delay = null; browser.urlChange(input.val()); } }; }); } ]); root.bind('click',function (E) { e.stopPropagation(); }); } initEnv('html5'); initEnv('hashbang'); </script> </body> </html>

五、附加说明

  1. @H_403_5@Page reload navigation
    $LOCATIOn服务仅仅允许我们改变URl;它不允许我们重新加载页面(reload the page)。当我们需要改变URL且reload page或者跳转到其他页面时,我们需要使用低级点得API,$window.LOCATIOn.href。

  2. @H_403_5@Using $LOCATIOn outside of the scope life-cycle
    $LOCATIOn知道angular的scope life-cycle。当浏览器的URL发生改变时,它会更新$LOCATIOn,并且调用$apply,所以所有$watcher和$observer都会得到通知。当我们再$digest阶段中@L_673_1@$LOCATIOn,不会出现任何问题;$LOCATIOn会将这次@L_673_1@传播到浏览器中,并且通知所有$watcher、$observer。当我们需要在angular外面改变$LOCATIOn时(例如在DOM事件中或者在测试中),我们必须调用$apply,以传播这个变化。

  3. @H_403_5@$LOCATIOn.path() and ! or / prefixes
    path可以直接使用”/”开始;$LOCATIOn.path()setter会在value没有以”/”开头时自动补上。
    注意”!”前缀,在Hashbang mode中,不属于$LOCATIOn.path()的一部分。它仅仅是hashPrefix。

六、TesTing with the $LOCATIOn service

@H_403_5@在测试中使用的$LOCATIOn服务的处于scope的life-cycle之外。这意味着我们需要主动负责调用scope.apply()。

describe('serviceUnderTest',function() {
    beforeEach(module(function($provide) {
      $provide.factory('serviceUnderTest',function($LOCATIOn){
      // whatever it does...
      });
    });
    it('should...',inject(function($LOCATIOn,$rootScope,serviceUnderTest) {
      $LOCATIOn.path('/new/path');
      $rootScope.$apply();
      // test whatever the service should do...
    }));
});

七、Migrating from earlier AngularJS releases

@H_403_5@  在早期的angular中,$LOCATIOn使用hashPath或者hashSearch去处理path和search方法在这个release中,当有需要的时候,$LOCATIOn服务处理path和search方法,然后使用那些获得得信息去构成hashbang URL(例如http://server.com/#!/path?search=a)。

八、Two-way binding to $LOCATIOn

@H_403_5@  angular compiler当前不支持方法的双向绑定(https://github.com/angular/angular.js/issues/404)。如果我们希望对 location@H_616_1034@@H_994_1058@input使ng@H_941_1137@m@H_944_1141@odeldirective@H_753_1281@modellocationPath watch,监听两个方向上的$LOCATIOn更新,例如:

<input type="text" ng-model="LOCATIOnPath" />
$scope.$watch('LOCATIOnPath',function(path) {
    $LOCATIOn.path(path);
);
$scope.$watch('$LOCATIOn.path()',function(path) {
    scope.LOCATIOnPath = path;
});

大佬总结

以上是大佬教程为你收集整理的AngularJS $location学习笔记全部内容,希望文章能够帮你解决AngularJS $location学习笔记所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。