$location服务是对所有浏览器中都存在的window.location对象的封装。那么,为什么需要使用$location服务,而不是直接使用window.location呢?
告别全局变量
关于全局变量,window.location是一个很好的例子(实际上,浏览器中的window和document两个对象也是很好的例子)。如果你的应用中存在全局变量,那么对它的测试、维护以及使用都会很麻烦(即使目前没有造成麻烦,但是长远来看必然会)。$location服务将会屏蔽这种污染(我们一般把全局变量称为全局空间污染);同时,当你进行单元测试的时候,可以利用$location服务注入假数据,从而可以测试浏览器的location细节。
API
可以使用window.location来访问浏览器location的全部内容。但是,window.location提供的是字符串形式的信息,而$location可以提供一些更加好用的、jQuery风格的getter和setter,从而可以用简洁的方式来使用这个对象。
AngularJS集成
如果使用$location,那么就可以按照任何你喜欢的方式来使用。而如果使用window.location,当其中的内容发生变化时,你需要自已通知AngularJS,并且需要负责监听。
HTML5集成
$location服务非常智能,它能够感受到浏览器是否可以使用HTML5 API。如果可以,它会自动使用这些API;如果不可以,它会回退并使用默认的处理方式。
那么,什么时候应该使用$location服务呢?一是需要对URL的变化做出响应($route服务没有包含此功能,$route服务主要用来处理基于URL的视图)的情况;二是需要针对浏览器当前的URL触发一次change事件的情况。
我们通过一个很小的例子来看看在真实的应用中应该如何使用$location服务。考虑这样一种情况:我们有一个日期选择器(datepicker),选择了日期之后,应用会导航到一个特定的URL。我们来看这种情况:
//假设日期选择器会使用日期来调用$scope.dateSelected $scope.dateSelected = function(dateTxt) { $location.path('/filteredResults?startDate=' + dateTxt); //如果这件事情已经在其他库的回调函数(例如jQuery)中做过了,那么我们还必须加上下面这行调用 $scope.$apply(); };
$location对象上还有哪些可以用的方法呢?下表列出了一个概要介绍,在遇到困难时可以查阅。
我们来看看$location服务将会具有怎样的行为,假设浏览器中的URL是http://www.host.com/base/index.html#!/path?param1=value1L#hashValue。上表中的setter函数一列中带有一些参数取值实例,示范了setter函数所期望的对象类型。
注意,search()这个setter函数有很多操作模式:
1.在调用search(searchObj)时,如果使用一个对象<string, string>作为参数,那么对象上的所有键和值都会被当作参数对待。
2.调用search(string)会把q=String直接设置到URL上。
3.使用一个字符串加一个值的方式来调用search(param,value),将会直接设置URL中指定的搜索参数;而使用null调用它,会删除URL中指定的参数。
使用这些setter中的任何一个都不意味着window.location会立即改变!$location服务融合在Angular的生命周期中,location的所有变化都会被聚集到一起,然后在周期结束的时候批量生效。所以,你可以一个接一个地随意修改,而不用担心用户会看到这些URL在闪烁变化。
文章来源:《用AngularJS开发下一代Web应用》