美文网首页WEB全栈技术
AngularJS中的URL里面的#号,到底起什么作用?

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

作者: 全栈开发之道 | 来源:发表于2017-12-16 09:54 被阅读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应该是这个样子:

    • http://localhost:3000/
      它的后面没有#号。 一旦出现了#号,说明这个首页由多个子页面(ng-view)组成。

    (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: '/'
        });
    }]);
    

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

    • config()函数是一个配置函数,它使用 $routeProvider 这样的一个服务;

    • when: 代表当你访问这个"/" 根路径时,去访问 templateUrl中的那个模板。 这里是 partials/home.html, 这里一定要注意html所在的文件目录(路径), 这里的 partials 文件夹位于public 文件夹下。 一个文件夹就是一个目录。
      controller,顾名思义,就是为视图(html文件)配套的控制器(controller)。需要注意是,这里的controller 只是应用于 templateUrl所对应的html文件(视图)。 视图与控制器,是MVC设计模式中必不可少的一对。

    • otherwise函数,当路径访问错误时,跳转到这个默认的页面。


    以上是路由控制器文件,与此相对应的是 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

    相关文章

      网友评论

        本文标题:AngularJS中的URL里面的#号,到底起什么作用?

        本文链接:https://www.haomeiwen.com/subject/fyzjwxtx.html