routeProvider
In a previous post about testing I mentioned that route resolves can make authoring unit tests for a controller easier. Resolves can also help the user experience.
A resolve is a property you can attach to a route in both ngRoute and the more robust UI router. A resolve contains one or more promises that must resolve successfully before the route will change. This means you can wait for data to become available before showing a view, and simplify the initialization of the model inside a controller because the initial data is given to the controller instead of the controller needing to go out and fetch the data.
As an example, let’s use the following simple service which uses $q to simulate the async work required to fetch some data.
app.factory( "messageService" , function ($q){ return { getMessage: function (){ return $q.when( "Hello World!" ); } }; }); |
And now the routing configuration that will use the service in a resolve.
$routeProvider .when( "/news" , { templateUrl: "newsView.html" , controller: "newsController" , resolve: { message: function (messageService){ return messageService.getMessage(); } } }) |
Resolve is a property on the routing configuration, and each property on resolve can be an injectable function (meaning it can ask for service dependencies). The function should return a promise.
When the promise completes successfully, the resolve property (message in this scenario) is available to inject into a controller function. In other words, all a controller needs to do to grab data gathered during resolve is to ask for the data using the same name as the resolve property (message).
app.controller( "newsController" , function (message) { $scope.message = message; }); |
You can work with multiple resolve properties. As an example, let’s introduce a 2nd service. Unlike the messageService, this service is a little bit slow.
app.factory( "greetingService" , function ($q, $timeout){ return { getGreeting: function (){ var deferred = $q.defer(); $timeout( function (){ deferred.resolve( "Allo!" ); },2000); return deferred.promise; } } }); |
Now the resolve in the routing configuration has two promise producing functions.
.when( "/news" , { templateUrl: "newsView.html" , controller: "newsController" , resolve: { message: function (messageService){ return messageService.getMessage(); }, greeting: function (greetingService){ return greetingService.getGreeting(); } } }) |
And the associated controller can ask for both message and greeting.
app.controller( "newsController" , function ($scope, message, greeting) { $scope.message = message; $scope.greeting = greeting; }); |
Composing Resolve
Although there are benefits to moving code out of a controller, there are also drawbacks to having code inside the route definitions. For controllers that require a complicated setup I like to use a small service dedicated to providing resolve features for a controller. The service relies heavily on promise composition and might look like the following.
app.factory( "newsControllerInitialData" , function (messageService, greetingService, $q) { return function () { var message = messageService.getMessage(); var greeting = greetingService.getGreeting(); return $q.all([message, greeting]).then( function (results){ return { message: results[0], greeting: results[1] }; }); } }); |
Not only is the code inside a service easier to test than the code inside a route definition, but the route definitions are also easier to read.
.when( "/news" , { templateUrl: "newsView.html" , controller: "newsController" , resolve: { initialData: function (newsControllerInitialData){ return newsControllerInitialData(); } } }) |
And the controller is also easy.
app.controller( "newsController" , function ($scope, initialData) { $scope.message = initialData.message; $scope.greeting = initialData.greeting; }); |
One of the keys to all of this working is $q.all, which is a beautiful way to compose promises and run requests in parallel.
routeProvider的更多相关文章
- AgularJS中Unknown provider: $routeProvider解决方案
最近在学习AgularJS, 做到http://angularjs.cn/A00a这一步时发现没有办法执行路由功能, 后来翻看控制台日志,发现提示Unknown provider: $routePro ...
- routeProvider路由的使用
先创建一个主程序文件index.html,内容如下: <!DOCTYPE html> <html ng-app="myApp"> <head> ...
- angularJS $routeProvider
O'Reilly书上的伪代码 var someModule = angular.module('someModule',[...module dependencies]); someModule.co ...
- AngularJS---Unknown provider: $routeProvider
AngularJS路由报错: Unknown provider: $routeProvider 根据先知们的指引,在网上爬贴,有翻到官方的解决文章. 原来在AgularJS1.2.0及其之后的版本中, ...
- 26.angularJS $routeProvider
转自:https://www.cnblogs.com/best/tag/Angular/ O'Reilly书上的伪代码 var someModule = angular.module('someMod ...
- AngularJS实例实战
学习了这么多天的AngularJS,今天想从实战的角度和大家分享一个简单的Demo--用户查询系统,以巩固之前所学知识.功能需求需要满足两点 1.查询所有用户信息,并在前端展示 2.根据id查询用户信 ...
- Nodejs之MEAN栈开发(七)---- 用Angular创建单页应用(下)
上一节我们走通了基本的SPA基础结构,这一节会更彻底的将后端的视图.路由.控制器全部移到前端.篇幅比较长,主要分页面改造.使用AngularUI两大部分以及一些优化路由.使用Angular的其他指令的 ...
- Nodejs之MEAN栈开发(六)---- 用Angular创建单页应用(上)
在上一节中我们学会了如何在页面中添加一个组件以及一些基本的Angular知识,而这一节将用Angular来创建一个单页应用(SPA).这意味着,取代我们之前用Express在服务端运行整个网站逻辑的方 ...
- AngularJs之八
***今天讲一下angularJs的路由功能: 一:angularJs路由. 1.AngularJS 路由允许我们通过不同的 URL 访问不同的内容. 2.通过 AngularJS 可以实现多视图的单 ...
随机推荐
- 关于我们DOM的知识点
DOM的概念及子节点类型 前言 DOM的作用是将网页转为一个javascript对象,从而可以使用javascript对网页进行各种操作(比如增删内容).浏览器会根据DOM模型,将HTML文档解析 ...
- hdu 5317 RGCDQ(前缀和)
题目链接:hdu 5317 这题看数据量就知道需要先预处理,然后对每个询问都需要在 O(logn) 以下的复杂度求出,由数学规律可以推出 1 <= F(x) <= 7,所以对每组(L, R ...
- Spring Boot修改内置Tomcat端口号 (zhuan)
http://blog.csdn.net/argel_lj/article/details/49851625 ********************************************* ...
- JS 的子父级页面调用
window.frames["iframevehquery"].add(); // 父页面调用嵌套子页面的js函数, iframevehquery 为 iframe 的name值, ...
- 开机使用root用户登录
有的fedora版本默认不支持开机以root用户登录,这是出于安全机制的考虑,可以通过设置实现开机root用户登录 步骤: 1.修改.etc/pam.d/gdm文件,注释掉auth pam_succ ...
- eclipse下安装插件
最近想自己弄弄Python,手上就有eclipse,也不想在安装别的IDE占空间,就在网上找了一下eclipse支持开发python的插件,果然有. pydev官网地址:http://pydev.or ...
- VC++时间函数总结
目录 第1章基本概念 1 1.1 基本概念 1 1.2 时间表示法 2 第2章 Win32 API 3 2.1 获取 3 2.1.1 时间间隔 3 2.1.2 时刻 ...
- 如何设计一个RPC系统
版权声明:本文由韩伟原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/162 来源:腾云阁 https://www.qclou ...
- Docker 使用指南 (六)—— 使用 Docker 部署 Django 容器栈
版权声明:本文由田飞雨原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/98 来源:腾云阁 https://www.qclou ...
- rand()和srand()GetTickCount函数用法
标准库<cstdlib>(被包含于<iostream>中)提供两个帮助生成伪随机数的函数: 函数一:int rand(void):从srand (seed)中指定的seed开始 ...