TAT.yunsheng 初涉Angular:认识与使用$location服务
In 未分类 on 2015年04月22日 by view: 6,146
8

前言

笔者驽钝,最近由于工作关系才去学习了Angular,发现在合适的项目下使用Angular开发真是非常畅快!MVC框架需要一些学习成本才能上手,再加上Angular采用现在通行的约定优于配置(convention over configuration)理念,框架本身做了很多封装,所以实现起来需要开发人员对框架足够的熟悉。

Angular一个典型的使用场景就是单页应用,那么如何在一个单页面中改变URL,请与笔者一同学习。

$location

Angular中使用内置的$location服务来监听、操作URL,包括如下功能:

  • 获取、监听、改变地址栏的URL
  • 与URL实现双向数据绑定(地址栏变动、前进后退或者点击页面的链接均会触发)。
  • 将URL对象封装成了一套方法(protocol、host、port、path、search和hash)

相对于BOM原生的window.location,使用$location更利于测试用例的编写(通过$location来注入假数据),提供的接口也更友好(官方一直强调是jQuery-style getters and setters,我的理解就是支持链式写法),与URL实现了双向绑定,内部集成了HTML5的History API,所以建议使用$location服务。

如果想实现类似history.replaceState()的功能,可以使用replace方法,代码如下。本方法只会实现一次replace历史记录的功能。

$location处于Angular的生命周期内,单个周期内的改变会统一在周期结束时生效,所以不必担心每次改变了$location,URL都会立刻变化。

注意:$location无法使整个页面重新加载。如果改变URL后希望重新加载页面,请使用$window.location.href。

配置$location

配置$location服务,需要用$locationProvider设置参数:

  • html5Mode(mode): {boolean|Object}

    • true or enabled:true – 设置为 HTML5 mode
    • false or enabled:false – 设置为 Hashbang mode
    • requireBase:true – 不需要根目录 default: enabled:false
  • hashPrefix(prefix): {string} Hashbang风格的URL中#号前面的前缀,习惯上用"!",虽然默认是""(没有!的#怎么能叫shebang呢。。)

$locationProvider用于配置应用中Deep Linking的存储方式,就提供了上述两个配置接口。

Hashbang模式

$location服务支持配置两种URL格式:Hashbang模式(默认)和HTML5模式。两种模式下的API都是通用的。如下图

image

所谓的Hashbang就是在URL里会看到#,所有的路由变化都是在hash里面控制的,具体到URL长这样:https://docs.angularjs.org/#!/guide/introduction?search=test

如果我们用原生的window.location打印,会发现变化的部分其实都是在hash里,略eggache。

image

好处是各个浏览器都兼容,坏处是URL长相奇特,SEO也不友好。

HTML5模式

所以Angular提供了HTML5模式。使用了HTML5的History API来控制URL的变化,不再有啰嗦的#。浏览器的兼容性可参考这里。鉴于兼容性和Angular内部的封装,建议采用本模式。

Angular内部做了向下兼容,采用本模式后,在低版本的浏览器仍会用Hashbang来降级处理,两种模式的URL也能自动实现相互转换,无需开发者关注。不过,以下三种情况,Angular不会做转换:

  • 带有target的链接 <a href="/ext/link?a=b" target="_self">link</a>
  • 跳往其他域名的绝对路径 <a href="http://angularjs.org/">link</a>
  • 非当前根路径下的链接 <a href="/not-my-base/link">link</a>

记得设置页面的根目录

如果你的应用挂在根目录(https://myapp.com/),则设置为:

如果挂在子目录(https://myapp.com/subapp/),则设置为:

不设置会导致Angular无法正确处理相对链接和回退到hashbang模式。

服务端也要做相应的配置!

因为是单页应用,所以其他链接请求到服务器时,根本找不到对应的html,就会忧伤的返回404。所以需要将所有到应用根路径下的请求都重定向到某个页面(比如index.html)。这样浏览器里先由index.html启动应用,Angular发现URL变化了再定位到真正请求的路由上。

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2015/04/angular-location/

  1. 码克斯列农 2016 年 7 月 25 日

    我来读这篇文章,主要就是不明白html5mode到底有什么好处,因为Shebang对Google的SEO是其实是友好的,有助于ajax内容的索引,你文章中提到的与这点相反“好处是各个浏览器都兼容,坏处是URL长相奇特,SEO也不友好。”。从你的文章看,好处也只是提到通过historyAPI美化了URL,而对SEO的影响没有深入探讨。

  2. 孟楠 2015 年 11 月 20 日

    最近在用angular,想请教一下html5模式 在服务器端如何配置文件

    • TAT.yunsheng

      TAT.yunsheng 2016 年 2 月 29 日

      最后一段有解释呀

  3. mon 2015 年 5 月 18 日

    蜘蛛已经可以很好的解析#的链接的

  4. TAT.tennylv

    TAT.tennylv 2015 年 4 月 24 日

    好文 通俗易懂!

  5. 4074 2015 年 4 月 22 日

    感觉有点水~~

    • TAT.yunsheng

      TAT.yunsheng 2015 年 4 月 23 日

      不好意思,Angular算是新手,有何不对愿闻其详

发表评论