利用Angularjs中模块ui-route管理状态的方法


Posted in Javascript onDecember 27, 2016

ui-router 的工作原理非常类似于 Angular 的路由控制器,但它只关注状态。

  • 在应用程序的整个用户界面和导航中,一个状态对应于一个页面位置
  • 通过定义controller、template和view等属性,来定义指定位置的用户界面和界面行为
  • 通过嵌套的方式来解决页面中的一些重复出现的部位

最简单的形式

模板可以通过下面这种最简单的方式来指定

<!-- in index.html -->
<body ng-controller="MainCtrl">
 <section ui-view></section>
</body>
// in app-states.js (or whatever you want to name it)
$stateProvider.state('contacts', {
 template: '<h1>My Contacts</h1>'
})

模板将被插入哪里?

状态被激活时,它的模板会自动插入到父状态对应的模板中包含ui-view属性的元素内部。如果是顶层的状态,那么它的父模板就是index.html。

激活状态

有三种方法来激活状态:

  1. 调用$state.go()方法,这是一个高级的便利方法。
  2. 点击包含ui-sref指令的链接。
  3. 导航到与状态相关联的 url。

Templates 模板

可以通过下面几种方法来配置一个状态的模板。 方法一:配置template属性,指定一段 HTML 字符串,这人是设置模板的最简单的方式。

$stateProvider.state(<span class="hljs-string">'contacts'</span>, {
 template: <span class="hljs-string">'<h1>My Contacts</h1>'</span>
})

方法二:配置templateUrl属性,来加载指定位置的模板,这是设置模板的常用方法。

$stateProvider.state(<span class="hljs-string">'contacts'</span>, {
 templateUrl: <span class="hljs-string">'contacts.html'</span>
})

templateUrl 的值也可以是一个函数返回的url,函数带一个预设参数stateParams。

方法三:通过 templateProvider 函数返回模板的 HTML。

<span class="hljs-variable">$stateProvider</span>.state(<span class="hljs-string">'contacts'</span>, {
 templateProvider: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$timeout</span>, <span class="hljs-variable">$stateParams</span>)</span> </span>{
 <span class="hljs-keyword">return</span> <span class="hljs-variable">$timeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{
 <span class="hljs-keyword">return</span> <span class="hljs-string">'<h1>'</span> + <span class="hljs-variable">$stateParams</span>.contactId + <span class="hljs-string">'</h1>'</span>
 }, <span class="hljs-number">100</span>);
 }
})

如果想在状态被激活前,让<ui-view>有一些默认的内容,当状态被激活之后默认内容将被状态对应的模板替换。

<span class="hljs-tag"><<span class="hljs-title">body</span>></span>
 <span class="hljs-tag"><<span class="hljs-title">ui-view</span>></span>
 <span class="hljs-tag"><<span class="hljs-title">i</span>></span>Some content will load here!<span class="hljs-tag"></<span class="hljs-title">i</span>></span>
 <span class="hljs-tag"></<span class="hljs-title">ui-view</span>></span>
<span class="hljs-tag"></<span class="hljs-title">body</span>></span>

Controllers 控制器

可以为模板指定一个控制器(controller)。警告:控制器不会被实例化如果模板没有定义。 设置控制器:

$stateProvider.state('contacts', {
 <span class="hljs-keyword">template</span>: '<h1>{{title}}</h1>',
 controller: function($scope){
 $scope.title = '<span class="hljs-type">My</span> <span class="hljs-type">Contacts</span>';
 }
})

如果在模块中已经定义了一个控制器,只需要指定控制器的名称即可:

$stateProvider.state(<span class="hljs-string">'contacts'</span>, {
 template: <span class="hljs-keyword">...</span>,
 controller: <span class="hljs-string">'ContactsCtrl'</span>
})

使用 controllerAs语法:

$stateProvider.state(<span class="hljs-string">'contacts'</span>, {
 template: <span class="hljs-keyword">...</span>,
 controller: <span class="hljs-string">'ContactsCtrl as contact'</span>
})

对于更高级的需要,可以使用controllerProvider来动态返回一个控制器函数或字符串:

$stateProvider.state(<span class="hljs-string">'contacts'</span>, {
 template: <span class="hljs-keyword">...</span>,
 controllerProvider: <span class="hljs-keyword">function</span>($stateParams) {
 var ctrlName = $stateParams.type + <span class="hljs-string">"Controller"</span>;
 <span class="hljs-keyword">return</span> ctrlName;
 }
})

控制器可以使用 $scope.on()方法来监听事件状态转换。 控制器可以根据需要实例化,当相应的 scope 被创建时。例如,当用户点击一个 url 手动导航一个状态时,$stateProvider 将加载对应的模板到视图中,并且将控制器和模板的 scope 绑定在一起。

解决器 Resolver

可以使用 resolver 为控制器提供可选的依赖注入项。 resolver 配置项是一个由key/value构成的对象。

    key ? {string} :注入控制器的依赖项名称。

    factory ? {string|function}

          1、string:一个服务的别名

          2、function:函数的返回值将作为依赖注入项,如果函数是一个耗时的操作,那么控制器必须等待该函数执行完成(be resolved)才会被实例化。

          例子

          在 controller 实例化之前,resolve 中的每一个对象都必须 be resolved,请注意每个 resolved object 是怎样作为参数注入到控制器中的。

<span class="hljs-variable">$stateProvider</span>.state(<span class="hljs-string">'myState'</span>, {
 resolve:{
 
 <span class="hljs-comment">// Example using function with simple return value.</span>
 <span class="hljs-comment">// Since it's not a promise, it resolves immediately.</span>
 simpleObj: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span></span>{
 <span class="hljs-keyword">return</span> {value: <span class="hljs-string">'simple!'</span>};
 },
 
 <span class="hljs-comment">// Example using function with returned promise.</span>
 <span class="hljs-comment">// 这是一种典型使用方式</span>
 <span class="hljs-comment">// 请给函数注入任何想要的服务依赖,例如 $http</span>
 promiseObj: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(<span class="hljs-variable">$http</span>)</span></span>{
 <span class="hljs-comment">// $http returns a promise for the url data</span>
 <span class="hljs-keyword">return</span> <span class="hljs-variable">$http</span>({method: <span class="hljs-string">'GET'</span>, url: <span class="hljs-string">'/someUrl'</span>});
 },
 
 <span class="hljs-comment">// Another promise example. </span>
 <span class="hljs-comment">// 如果想对返回结果进行处理, 可以使用 .then 方法</span>
 <span class="hljs-comment">// 这是另一种典型使用方式</span>
 promiseObj2: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(<span class="hljs-variable">$http</span>)</span></span>{
 <span class="hljs-keyword">return</span> <span class="hljs-variable">$http</span>({method: <span class="hljs-string">'GET'</span>, url: <span class="hljs-string">'/someUrl'</span>})
  .then (<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(data)</span> </span>{
  <span class="hljs-keyword">return</span> doSomeStuffFirst(data);
  });
 }, 
 
 <span class="hljs-comment">// 使用服务名的例子,这将在模块中查找名称为 'translations' 的服务,并返回该服务 </span>
 <span class="hljs-comment">// Note: The service could return a promise and</span>
 <span class="hljs-comment">// it would work just like the example above</span>
 translations: <span class="hljs-string">"translations"</span>,
 
 <span class="hljs-comment">// 将服务模块作为解决函数的依赖项,通过参数传入</span>
 <span class="hljs-comment">// 提示:依赖项 $stateParams 代表 url 中的参数</span>
 translations2: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(translations, <span class="hljs-variable">$stateParams</span>)</span></span>{
  <span class="hljs-comment">// Assume that getLang is a service method</span>
  <span class="hljs-comment">// that uses $http to fetch some translations.</span>
  <span class="hljs-comment">// Also assume our url was "/:lang/home".</span>
  translations.getLang(<span class="hljs-variable">$stateParams</span>.lang);
 },
 
 <span class="hljs-comment">// Example showing returning of custom made promise</span>
 greeting: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(<span class="hljs-variable">$q</span>, <span class="hljs-variable">$timeout</span>)</span></span>{
  <span class="hljs-keyword">var</span> deferred = <span class="hljs-variable">$q</span>.defer();
  <span class="hljs-variable">$timeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
  deferred.resolve(<span class="hljs-string">'Hello!'</span>);
  }, <span class="hljs-number">1000</span>);
  <span class="hljs-keyword">return</span> deferred.promise;
 }
 },
 
 <span class="hljs-comment">// 控制器将等待上面的解决项都被解决后才被实例化</span>
 controller: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(<span class="hljs-variable">$scope</span>, simpleObj, promiseObj, promiseObj2, translations, translations2, greeting)</span></span>{
 
 <span class="hljs-variable">$scope</span>.simple = simpleObj.value;
 
 <span class="hljs-comment">// 这里可以放心使用 promiseObj 中的对象</span>
 <span class="hljs-variable">$scope</span>.items = promiseObj.items;
 <span class="hljs-variable">$scope</span>.items = promiseObj2.items;
 
 <span class="hljs-variable">$scope</span>.title = translations.getLang(<span class="hljs-string">"english"</span>).title;
 <span class="hljs-variable">$scope</span>.title = translations2.title;
 
 <span class="hljs-variable">$scope</span>.greeting = greeting;
 }
})

为 $state 对象提供自定义数据

可以给 $state 对象提供自定义数据(建议使用data属性,以免冲突)

<span class="hljs-comment">// 基于对象和基于字符串定义 state 的例子</span>
<span class="hljs-keyword">var</span> contacts = { 
name: <span class="hljs-string">'contacts'</span>,
templateUrl: <span class="hljs-string">'contacts.html'</span>,
data: {
 customData1: <span class="hljs-number">5</span>,
 customData2: <span class="hljs-string">"blue"</span>
} 
}
$stateProvider
.state(contacts)
.state(<span class="hljs-string">'contacts.list'</span>, {
templateUrl: <span class="hljs-string">'contacts.list.html'</span>,
data: {
 customData1: <span class="hljs-number">44</span>,
 customData2: <span class="hljs-string">"red"</span>
} 
})

可以通过下面的方式来访问上面定义的数据:

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Ctrl</span><span class="hljs-params">(<span class="hljs-variable">$state</span>)</span></span>{
console.log(<span class="hljs-variable">$state</span>.current.data.customData1) <span class="hljs-comment">// 输出 5;</span>
console.log(<span class="hljs-variable">$state</span>.current.data.customData2) <span class="hljs-comment">// 输出 "blue";</span>
}

onEnter 和 onExit 回调函数

onEnter和onExit回调函数是可选配置项,分别称为当一个状态变得活跃的和不活跃的时候触发。回调函数也可以访问所有解决依赖项。

$stateProvider.state(<span class="hljs-string">"contacts"</span>, {
template: <span class="hljs-string">'<h1>{{title}}</h1>'</span>,
resolve: { title: <span class="hljs-string">'My Contacts'</span> },
controller: <span class="hljs-keyword">function</span>($scope, title){
$scope.title = <span class="hljs-string">'My Contacts'</span>;
},
// title 是解决依赖项,这里也是可以使用解决依赖项的
onEnter: <span class="hljs-keyword">function</span>(title){ 
<span class="hljs-keyword">if</span>(title){ <span class="hljs-keyword">...</span> do something <span class="hljs-keyword">...</span> }
},
// title 是解决依赖项,这里也是可以使用解决依赖项的
onExit: <span class="hljs-keyword">function</span>(title){
<span class="hljs-keyword">if</span>(title){ <span class="hljs-keyword">...</span> do something <span class="hljs-keyword">...</span> }
}
})

State Change Events 状态改变事件

所有这些事件都是在$rootScope作用域触发

$stateChangeStart ? 当模板开始解析之前触发

$rootScope.$on(<span class="hljs-string">'$stateChangeStart'</span>, 
<span class="hljs-keyword">function</span>(event, toState, toParams, fromState, fromParams){ <span class="hljs-keyword">...</span> })

注意:使用event.preventDefault()可以阻止模板解析的发生

<span class="hljs-variable">$rootScope</span>.<span class="hljs-variable">$on</span>(<span class="hljs-string">'$stateChangeStart'</span>, 
<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(event, toState, toParams, fromState, fromParams)</span></span>{ 
 event.preventDefault(); 
 <span class="hljs-comment">// transitionTo() promise will be rejected with </span>
 <span class="hljs-comment">// a 'transition prevented' error</span>
})

 $stateNotFound ? v0.3.0 ? 在 transition 时通过状态名查找状态,当状态无法找到时发生。该事件在 scope 链上广播,只允许一次处理错误的机会。unfoundState将作为参数传入事件监听函数,下面例子中可以看到unfoundState的三个属性。使用 event.preventDefault() 来阻止模板解析.

// somewhere, assume lazy.<span class="hljs-keyword">state</span> has not been defined
<span class="hljs-variable">$state</span>.go(<span class="hljs-string">"lazy.state"</span>, {a:<span class="hljs-number">1</span>, b:<span class="hljs-number">2</span>}, {inherit:false});
// somewhere else
<span class="hljs-variable">$scope</span>.<span class="hljs-variable">$on</span>('<span class="hljs-variable">$stateNotFound</span>', 
function(event, unfoundState, <span class="hljs-keyword">from</span>State, <span class="hljs-keyword">from</span>Params){ 
 console.<span class="hljs-keyword">log</span>(unfoundState.<span class="hljs-keyword">to</span>); // <span class="hljs-string">"lazy.state"</span>
 console.<span class="hljs-keyword">log</span>(unfoundState.<span class="hljs-keyword">to</span>Params); // {a:<span class="hljs-number">1</span>, b:<span class="hljs-number">2</span>}
 console.<span class="hljs-keyword">log</span>(unfoundState.options); // {inherit:false} + <span class="hljs-keyword">default</span> options
})

$stateChangeSuccess ? 当模板解析完成后触发

$rootScope.$on(<span class="hljs-string">'$stateChangeSuccess'</span>, 
<span class="hljs-keyword">function</span>(event, toState, toParams, fromState, fromParams){ <span class="hljs-keyword">...</span> })

$stateChangeError ? 当模板解析过程中发生错误时触发

$rootScope.$on(<span class="hljs-string">'$stateChangeError'</span>, 
<span class="hljs-keyword">function</span>(event, toState, toParams, fromState, fromParams, error){ <span class="hljs-keyword">...</span> })

View Load Events 视图加载事件

$viewContentLoading ? 当视图开始加载,DOM渲染完成之前触发,该事件将在$scope链上广播此事件。

<span class="hljs-variable">$scope</span>.<span class="hljs-variable">$on</span>(<span class="hljs-string">'$viewContentLoading'</span>, 
<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(event, viewConfig)</span></span>{ 
 <span class="hljs-comment">// Access to all the view config properties.</span>
 <span class="hljs-comment">// and one special property 'targetView'</span>
 <span class="hljs-comment">// viewConfig.targetView </span>
});

$viewContentLoaded ? 当视图加载完成,DOM渲染完成之后触发,视图所在的$scope发出该事件。

$scope.$on(<span class="hljs-string">'$viewContentLoading'</span>, 
$scope.$on(<span class="hljs-string">'$viewContentLoaded'</span>, 
<span class="hljs-keyword">function</span>(event){ <span class="hljs-keyword">...</span> });

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
JavaScript中“+=”的应用
Feb 02 Javascript
JQuery 文本框回车跳到下一个文本框示例代码
Aug 30 Javascript
JavaScript中的getMilliseconds()方法使用详解
Jun 10 Javascript
通过jquery实现页面的动画效果(实例代码)
Sep 18 Javascript
微信小程序 MINA文件结构
Oct 17 Javascript
Vue 实用分页paging实例代码
Apr 12 Javascript
微信页面弹出键盘后iframe内容变空白的解决方案
Sep 20 Javascript
Vue.js 踩坑记之双向绑定
May 03 Javascript
如何根据业务封装自己的功能组件
Apr 19 Javascript
小程序接口的promise化的实现方法
Dec 11 Javascript
通过Kettle自定义jar包供javascript使用
Jan 29 Javascript
vue 页面跳转的实现方式
Jan 12 Vue.js
javascript十六进制数字和ASCII字符之间的转换方法
Dec 27 #Javascript
浅谈javascript中的数据类型转换
Dec 27 #Javascript
微信小程序开发探究
Dec 27 #Javascript
javascript replace()第二个参数为函数时的参数用法
Dec 26 #Javascript
javascript prototype原型详解(比较基础)
Dec 26 #Javascript
如何提高数据访问速度
Dec 26 #Javascript
Angular的模块化(代码分享)
Dec 26 #Javascript
You might like
PHP中数字检测is_numeric与ctype_digit的区别介绍
2012/10/04 PHP
PHP判断远程图片或文件是否存在的实现代码
2014/02/20 PHP
php学习笔记之面向对象
2014/11/08 PHP
PHP读书笔记_运算符详解
2016/07/01 PHP
PHP最常用的正则表达式
2017/02/13 PHP
PHP实现一维数组与二维数组去重功能示例
2018/05/24 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
javascript函数库-集合框架
2007/04/27 Javascript
Jquery 弹出层插件实现代码
2009/10/24 Javascript
js比较日期大小的方法
2015/05/12 Javascript
jQuery EasyUI 菜单与按钮之创建简单的菜单和链接按钮
2015/11/18 Javascript
jquery自定义右键菜单、全选、不连续选择
2016/03/01 Javascript
轻松搞定js表单验证
2016/10/13 Javascript
用js制作淘宝放大镜效果
2020/10/28 Javascript
js实现网页定位导航功能
2017/03/07 Javascript
Vue 过滤器filters及基本用法
2017/12/26 Javascript
jQuery插件实现弹性运动完整示例
2018/07/07 jQuery
vue框架搭建之axios使用教程
2018/07/11 Javascript
JavaScript引用类型之基本包装类型实例分析【Boolean、Number和String】
2018/08/09 Javascript
js 根据对象数组中的属性进行排序实现代码
2019/09/12 Javascript
vue-next/runtime-core 源码阅读指南详解
2019/10/25 Javascript
win7安装python生成随机数代码分享
2013/12/27 Python
Python实现针对中文排序的方法
2017/05/09 Python
django实现前后台交互实例
2017/08/07 Python
Python数据结构之双向链表的定义与使用方法示例
2018/01/16 Python
python数字类型math库原理解析
2020/03/02 Python
自定义Django_rest_framework_jwt登陆错误返回的解决
2020/10/18 Python
Python爬虫制作翻译程序的示例代码
2021/02/22 Python
阿联酋航空假期:Emirates Holidays
2018/03/20 全球购物
Rossignol金鸡美国官网:始于1907年法国百年雪具品牌
2019/03/06 全球购物
命名空间(namespace)和程序集(Assembly)有什么区别
2015/09/25 面试题
设备动力科岗位职责范本
2014/02/23 职场文书
中学生打架检讨书
2014/10/13 职场文书
民主评议党员个人总结
2015/02/13 职场文书
交通事故被告答辩状
2015/05/22 职场文书
校园广播站开场白
2015/06/01 职场文书