AngularJS $location学习笔记
AngularJS $location学习笔记一、$lacation能做什么? $location服务分析浏览器地址栏中的URL(基于window.location),让我们可以在应用中较为方便地使用URL里面的东东。在地址栏中更改URL,会响应到$location服务中,而在$location中修改URL,也会响应到地址栏中。 二、General overview of the API(API的总体概述) $location 服务可以根据它初始化时的配置而有不同的表现。默认配置是适合大多数应用的,其他配置定制,可以开启一些新特性。
// get the current path
$location.path();
// change the path
$location.path('/newValue')
所有setter方法都返回同一个$location对象,以实现链式语法。例如,在一句里面修改多个属性,链式setter方法类似: $location.path(‘/someNewPath’).replace(); 注意,setter方法不会马上更新window.location。相反,$location服务会知道scope生命周期以及合并多个$location变化为一个,并在scope的$digest阶段一并提交到window.location对象中。正因为$location多个状态的变化会合并为一个变化,到浏览器中,只调用一次replace()方法,让整个commit只有一个replace(),这样不会使浏览器创建额外的历史记录。一旦浏览器更新了,$location服务会通过replace()方法重置标志位,将来的变化将会创建一个新的历史记录,除非replace()被再次调用。 Setter and character encoding 三、Hashbang and HTML5 Modes $location服务有两个配置模式,可以控制浏览器地址栏的URL格式:Hashbang mode(默认)与基于使用HTML5 History API的HTML5 mode。在两种模式下,应用都使用相同的API,$location服务会与正确的URL片段、浏览器API一起协作,帮助我们进行浏览器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';
}
));
Crawling your app(让google能够对我们的应用进行索引) 四、HTML5 mode 在HTML5模式中,$location服务的getter、setter通过HTML5的History API与浏览器URL进行交互,允许使用正规的path、search模块,代替hashbang的模式。如果部分浏览器不支持HTML5 History API,$location服务会自动退回到使用hashbang URL的模式。为了让我们能够从不清楚显示我们的应用的浏览器是否支持history API的担心中解脱出来,使用$location服务是一个正确的、最佳的选择。
<!DOCTYPE html> <html ng-app> <head> <base href=""/> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>fake-browser</title> <meta 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>
五、附加说明
六、Testing with the $location service在测试中使用的$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在早期的angular中,$location使用hashPath或者hashSearch去处理path和search方法。在这个release中,当有需要的时候,$location服务处理path和search方法,然后使用那些获得得信息去构成hashbang URL(例如http://server.com/#!/path?search=a)。 八、Two-way binding to $location angular compiler当前不支持方法的双向绑定(https://github.com/angular/angular.js/issues/404)。如果我们希望对
<input type="text" ng-model="locationPath" />
$scope.$watch('locationPath',function(path) {
$location.path(path);
);
$scope.$watch('$location.path()',function(path) {
scope.locationPath = path;
});
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |