利用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 相关文章推荐
总结一些js自定义的函数
Aug 05 Javascript
让网页跳转到指定位置的jquery代码非书签
Sep 06 Javascript
IE中的File域无法清空使用jQuery重设File域
Apr 24 Javascript
jquery动态添加删除一行数据示例
Jun 12 Javascript
详解用webpack2搭建angular2的项目
Jun 22 Javascript
gulp安装以及打包合并的方法教程
Nov 19 Javascript
关于Vue的路由权限管理的示例代码
Mar 06 Javascript
angular5 httpclient的示例实战
Mar 12 Javascript
使用Angular CLI生成路由的方法
Mar 24 Javascript
jQuery实现的页面弹幕效果【测试可用】
Aug 17 jQuery
node.js使用 http-proxy 创建代理服务器操作示例
Feb 10 Javascript
vue+elementui 实现新增和修改共用一个弹框的完整代码
Jun 08 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 socke 向指定页面提交数据
2008/07/23 PHP
使用图灵api创建微信聊天机器人
2015/07/23 PHP
PHP微信支付实例解析
2016/07/22 PHP
详解PHP防止盗链防止迅雷下载的方法
2017/04/26 PHP
PHP延迟静态绑定的深入讲解
2018/04/02 PHP
利用JQuery为搜索栏增加tag提示
2009/06/22 Javascript
js如何实现设计模式中的模板方法
2013/07/23 Javascript
javascript 获取函数形参个数
2014/07/31 Javascript
JavaScript中的getTimezoneOffset()方法使用详解
2015/06/10 Javascript
js使用cookie记录用户名的方法
2015/11/26 Javascript
jQuery进行组件开发完整实例
2015/12/15 Javascript
使用JQuery 加载页面时调用JS的实现方法
2016/05/30 Javascript
Bootstrap Table使用方法详解
2016/08/01 Javascript
vue.js表格分页示例
2016/10/18 Javascript
JS日程管理插件FullCalendar中文说明文档
2017/02/06 Javascript
微信小程序 页面跳转传值实现代码
2017/07/27 Javascript
bootstrap table服务端实现分页效果
2017/08/10 Javascript
jquery radio 动态控制选中失效问题的解决方法
2018/02/28 jQuery
解决Vue.js由于延时显示了{{message}}引用界面的问题
2018/08/25 Javascript
聊聊vue 中的v-on参数问题
2021/01/29 Vue.js
Python对数据库操作
2016/03/28 Python
python语言使用技巧分享
2016/05/31 Python
Python中音频处理库pydub的使用教程
2017/06/07 Python
Python图像滤波处理操作示例【基于ImageFilter类】
2019/01/03 Python
Python反爬虫技术之防止IP地址被封杀的讲解
2019/01/09 Python
python接口自动化框架实战
2020/12/23 Python
SNIDEL官网:日本VIVI杂志人气少女第一品牌
2020/03/12 全球购物
LUISAVIAROMA德国官网:时尚奢侈品牌购物网站
2020/11/12 全球购物
简述DNS进行域名解析的过程
2013/12/02 面试题
机械设计制造专业个人求职信
2013/09/25 职场文书
《地震中的父与子》教学反思
2014/04/10 职场文书
党的群众教育实践活动实施方案
2014/06/12 职场文书
学校青年志愿者活动总结
2015/05/06 职场文书
2015年保险业务员工作总结
2015/05/27 职场文书
Python的这些库,你知道多少?
2021/06/09 Python
在Windows Server 2012上安装 .NET Framework 3.5 所遇到的问题
2022/04/29 Servers