WEB全栈技术

AngularJS中的URL里面的#号,到底起什么作用?

2017-12-16  本文已影响294人  全栈开发之道

序言:

通常来说,URL中出现#的情况并不多见。如果你发现了#,这多半说明,它是一个单页面应用,而AngularJS 是单页面的标志性框架。要想理解什么是单页面应用,就一定弄清楚前端路由控制器是怎么工作的。

URL的#问题

我们知道,AngularJS是一个强大的前端框架。AngularJS框架定义了自己的前前端路由控制器,通过不同URL实现单页面(ng-app)对视图(ng-view)的页面布局和刷新。

需要注意的一点: 一个基于AngularJS的Web应用,是由多个单页面组成的,而每个单页面是由多个前端子页面组成的。

一个单页面的URL中会包括一个#(hash)号,这个#用来区分这个URL是AngularJS管理的前端路径呢,还是WebServer 管理的服务器路径?

比如:下面的带有#号的URL,是AngularJS 管理的路径:

注意AngularJS单页面的特征

(1)AngularJS单页面中的 “单”是指: 一个单页面是一组页面,这一组页面由一个 ng-app管理和控制;这一个单页面只有一个URL。AngularJS实现了自己的前端路由,让一个ng-app可以管理多个URL,再对应到多个ng-view 上面。 具体来说:

如果不是单页面,URL应该是这个样子:

(2)单页面在URL访问时,一定要加上#号,比如:
http://localhost:3000/#/add-goods
如果遗漏#:http://localhost:3000/add-goods 浏览器就会报错: Not Found 404 。 这说明路由出了问题。

那么,带#号和不带#号,本质上有什么区别呢?
首先要透彻理解URL是干什么用的? 看到URL,我们会不假思索地认为,URL就是前端请求后台的。一个URL,就是前端向后台发出的一个请求,希望得到后台服务器的响应。

对于单页面而言,我们不想看到频繁的页面跳转,因为每一次跳转都是一个URL请求。那怎么办呢?

在URL中添加一个特殊的#号,规定带有#的URL 是前端路由。当浏览器看到URL带有#时,不再发送到服务器,而是发送给AngularJS,由AngularJS自行处理这个URL。

单页面应用场景

对于混合(Native + Web)框架的APP来说,如果用一般的html页面做APP,简单的页面可以用 <a href=""> </a> 这样的标签去链接时,速度还是可以的。当APP有多个Web页面时,页面之间的切换就没有那么流畅了。 再加上网速影响,页面的加载有些慢。这些用户体验的问题怎么解决呢? 这时候, AngularJS就派上用场了。

在AngularJS里面,可以用路由进行切换。用户在加载AngularJS页面时,会把整个单页面缓存到手机上,当用路由进行切换时,不用再发起HTTP请求,用户体验会提升很多。

回到课本上的项目案例,给出一段路由控制文件代码:

var app = angular.module('home_module', ['ngResource','ngRoute']);

app.config(['$routeProvider', function($routeProvider)
{
    $routeProvider
    .when('/', 
    {
        templateUrl: 'partials/home.html',
        controller:  'HomeCtrl'
    })

    .when('/add-goods', {
        templateUrl: 'partials/add-form.html',
        controller:  'AddGoodsCtrl'
    })

    .otherwise({
        redirectTo: '/'
    });
}]);

我们来逐行解读上面的这段代码:


以上是路由控制器文件,与此相对应的是 index.ejs 文件(视图),代码如下:

<!DOCTYPE html>

<html  ng-app='home_module' >
  <head>
    <link rel='stylesheet' href='/stylesheets/style.css' />
   <link rel='stylesheet' href='/stylesheets/bootstrap/css/bootstrap.min.css' />
    <script src= '/javascripts/libs/angularjs/angular.min.js' > 
    </script> 
    <script src= '/javascripts/libs/angularjs/angular-resource.min.js' > 
    </script> 
    <script src= '/javascripts/libs/angularjs/angular-route.min.js' > 
    </script> 
    <script src= "/javascripts/home_module.js" > </script> 
  </head>
  <body>
   <div ng-view> </div>
  </body>
</html>

以上这段代码,关键的一句是 <div ng-view> </div>。它是一个占位符。在程序运行时,它要被templateUrl对应的模板所替换。这个替换的过程,称之为模板注入。 比如注入:partials/home.html模板。

什么时候注入partials/home.html模板,这取决于路由配置。这里打一个形象的比喻:

路由控制器相当于一个遥控器,而ng-view相当于电视机的某个频道。当某个模板同当前的路由相关联时:

  1. 创建一个新的作用域。 相当于用路由控制器(遥控器)打开某个电视频道;
  2. 移除当前视图,同时该作用域也被清除; (换台)
  3. 将新的作用域通当前模板关联在一起; (换新的频道)
  4. 如果路由中有定义的控制器,就把对应的控制器与相应的模板关联起来;
  5. 触发 $viewContentLoaded 事件;
  6. 如果提供了 onload属性,调用该属性所指定的函数。

小结

理解“单页面应用”的概念,需要一个践行的过程。URL中#号的出现是一个“单页面”的一个标志性符号。这里面引入了一个新的概念叫——前端路由。 如果使用传统的一个URL对应一个页面,也就不存在什么前端路由的概念了。因为AngularJS是一个面向单页面的前端框架,自然需要一种方法来支持前端路由,而这正是URL中#号的意义所在!


参考书: 《 全栈开发之道:MongoDB+Express+AngularJS+Node.js

上一篇下一篇

猜你喜欢

热点阅读