IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    初涉Angular:认识与使用$location服务

    TAT.yunsheng发表于 2015-04-22 02:39:42
    love 0

    前言

    笔者驽钝,最近由于工作关系才去学习了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.path('/someNewPath');
    $location.replace();
    // or you can chain these as: 
    $location.path('/someNewPath').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.html5Mode(true).hashPrefix('!');
    

    $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的链接 link
    • 跳往其他域名的绝对路径 link
    • 非当前根路径下的链接 link

    记得设置页面的根目录。

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

    
      
      ...
    
    

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

    
      
      ...
    
    

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

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

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



沪ICP备19023445号-2号
友情链接