Kamutu Yeung

繁华渐欲迷人眼,切勿迷失其本心

  • 主页
所有文章 友链 关于我

Kamutu Yeung

繁华渐欲迷人眼,切勿迷失其本心

  • 主页

AngularJS - 路由入门

2016-05-10

我们有很多方法让一个视图随着用户的操作进行变化。
但是,只是单单一个视图就要满足所有的需求会让代码变得非常复杂。
也许我们可以使用ng-include来引用各种模板,但这只限于部分场景。

于是我们可以将视图拆分为两种:

布局视图
模板视图

如此一来,我们便可以使用route实现模板和布局视图的组装,以构建多视图的应用。

Route

ngRoutes并不属于核心模块,我们需要额外引用angular-route.js,并在声明应用时:

1
var myApp = angular.module('myApp',['ngRoute']);

$routeProvider

route需要通过$routeProvider定义,比如这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var myApp = angular.module('myApp', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
template: '<h2>contacts</h2>',
controller: 'myController'
})
.when('/contacts', {
templateUrl: 'contacts.html',
controller: 'contactsController'
})
.when('/contacts/:userId', {
templateUrl: 'contact.html',
controller: 'contactController'
})
.otherwise({redirectTo: '/'});
}]);

OMG,这种定义方式太晦涩了,我们不能像定义指令时用directive()那样用route()什么的吗?
其实directive()什么的都是config()的语法糖。

比如我们这样声明一个指令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var myApp = angular.module('myApp', [])
.directive('myDirective', function() {
return {
template: '<p>Kavlez</p>'
};
});
```
其实是:
```pythob
var myApp = angular.module('myApp', [])
.config(function($compileProvider){
$compileProvider.directive('myDirective', function() {
return {
template: '<p>Kavlez</p>'
};
});
});

provider用来实例化依赖并对外提供API,比如这里的$route服务就是通过相应的$routeProvider对外提供API,比如when(),我们通过这些API设置路由规则。

另外,provider是怎么来的?
Injector对module进行配置时,会在这些module中注册所有定义的provider,必要时会注入服务,而服务的实例化则需要provider来进行。
路由模式

不同的路由模式下URL会以不同的格式呈现,我们有两种模式可以选择。

标签模式
AngularJS默认使用这个模式,这个模式下URL会以'#'开头。

html5模式
这个模式下的URL和一般的没什么区别,如果选择了该模式,AngularJS会根据浏览器重写所有的<a href=""></a>。

路由模式也通过$routeProvider进行设置,比如:

1
2
3
4
5
var myApp = angular.module('myApp', ['ngRoute'])
.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode(false);
$locationProvider.hashPrefix('!');
}])

when

这里使用的when(path,route)一共两个参数。

path比较好理解,也就是路由路径,和$location.path匹配,后面带上:则表示参数,可以传递给$routeParams。
route指的是path匹配后的动作,是一个对象,属性有:
    controller (string/function):在这里声明的控制器会得到路由创建的作用域。
    template (string):HTML模板渲染到声明了ng-view的元素里。
    templateURL (string):功能和template一样,只是通过XHR获得模板。
    resolve : 将列表对象注入到controller中。
    redirectTo (string/function): 用于替换path。比起用作字符串,函数更有意义。
    reloadOnSearch (boolean):默认是true,也就是$location.search()发生变化时重新加载路由。

ng-view

我们用ng-view接收对应的视图模板,给$route对应的视图占位。
mg-view的优先级为1000,也就是说AngularJS不会运行同一个元素上的低优先级指令。

ngView指令遵循以下规则。

每次触发$routeChangeSuccess事件,视图都会更新。
如果某个模板同当前的路由相关联:
    创建一个新的作用域;
    移除上一个视图,同时上一个作用域也会被清除;
    将新的作用域同当前模板关联在一起;
    如果路由中有相关的定义,那么就把对应的控制器同当前作用域关联起来;
    触发$viewContentLoaded事件;
    如果提供了onload属性,调用该属性所指定的函数。

$location

既然涉及到了路径,就不得不说$location服务。
感觉和windows.location差不多,但$location只能用来在内部访问路由,无法刷新整个页面。

下面列出$location的常用的一些方法。

path()
当前路径:

$location.path();

跳转至:

$location.path('/');

replace()
这个方法可以让用户无法后退,比如这样:

$location.path('/').replace();

absUrl() : 获取绝对路径
hash() : 获取URL中的hash片段
host() : 获取host
port() : 获取端口号
protocol() : 获取协议

search() :
用于设置URL中的查询参数,比如:

$location.search({id:'000000',name:'Kavlez'});
$location.search('id=000000&name=Kavlez');

url() : 获取当前URL,或者修改当前URL

event

有几个路由相关的事件如下:

$routeChangeStart : 路由变化之前会触发该事件,有三个参数,分别是AngularJS事件对象、将要路由的url、当前url。

$rootScope.$on('$routeChangeStart', function(evt, next, current) {
    //something
});

$routeChangeSuccess : 路由成功后触发,三个参数分别为AngularJS事件对象、当前url、上一个url
$routeChangeError : 被拒时触发,三个参数为当前路由信息、上一个路由的信息、错误信息。
$routeUpdate : 如果reloadOnSearch为false,重新使用控制器的实力时触发。
赏

谢谢你请我吃糖果

  • angular

扫一扫,分享到微信

微信分享二维码
angular 深层嵌套ngRepeat中获取radio的值和checkbox的值
关于angular中在ng-repeat中ng-if、ng-click事件的当前索引参数问题
© 2018 Kamutu Yeung
Hexo Theme Yilia by Litten
  • 所有文章
  • 友链
  • 关于我

tag:

  • angular
  • apicloud
  • vue2.0
  • javascript
  • git
  • Nodejs
  • npm
  • chromedriver
  • vue报错
  • webpack
  • css
  • 前端
  • vue
  • 移动端适配
  • 面试
  • 小程序
  • github
  • 跨域
  • iframe

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

很惭愧

只做了一点微小的工作
谢谢大家