AngularJS:服务、服务器通信与视图组织
1. 服务与服务器通信
在处理异步通信时,我们常常需要考虑代码的放置位置以及数据的处理和错误处理。
1.1 代码放置位置
不能将代码放在
success
方法中,因为如果出现错误,表单会陷入工作状态,导致用户界面冲突。可以将代码同时放在
success
和
error
方法中,但更好的方式是使用
promise
对象的
finally
方法。无论
promise
被拒绝还是完成,
finally
方法都会被调用。
1.2 处理返回数据
异步通信往往不只是简单地发送数据,还需要处理服务器的响应数据。例如,用户名查找服务可能需要检查返回值,以确定给定的用户名是否存在于系统中。
promise.success(function (data, status) {
$scope.successMessage = "Your transaction identifier is " + data.transactionID;
$scope.showSuccessMessage = true;
});
这个例子假设从服务器收到了一个 JSON 响应,结构类似
{"transactionID": "12587965"}
。在实际项目中,可能会遇到不同的结构和格式,如 XML。
1.3 错误处理
应用程序会因为各种原因产生错误,有些可能与网络相关,有些可能是代码错误或配置问题。可以在
promise
对象的
error
方法中进行错误处理。
promise.error(function (data, status) {
if (status === 0) {
$scope.errorMessage = "network or http level issue";
} else {
$scope.errorMessage = "response HTTP status is " + status;
}
$scope.showErrorMessage = true;
});
这里使用了
status
参数,它会提供 HTTP 状态码,告诉我们服务器的响应情况。状态码在 200 到 299 之间被认为是成功的,在错误回调中不会看到这个范围内的状态码。如果服务器由于网络或 HTTP 级别的问题根本没有响应,会得到 0 作为结果。
2. 组织视图
AngularJS 在创建单页应用(SPA)方面表现出色。随着 HTML5 的发展和更快的互联网连接,SPA 变得越来越普遍。但在单页请求中下载大量内容时,会面临内容组织和管理的问题,Angular 路由系统可以很好地解决这个问题。
2.1 安装 ngRoute 模块
Angular 路由系统定义在可选模块
ngRoute
中,需要先下载并安装该模块。操作步骤如下:
1. 访问
http://angularjs.org
。
2. 点击
Download
。
3. 选择所需的版本(这里使用 1.2.5 版本)。
4. 点击
Extras
旁边显示的
Browse additional modules
链接。
5. 下载
angular-route.js
文件(或压缩版本
angular-route.min.js
)到
angularjs
文件夹。
在新的 HTML 文件中添加对
angular-route.js
文件的引用:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title></title>
<script src="angular.js"></script>
<script src="angular-route.js"></script>
</head>
<body>
<!-- body code here -->
</body>
</html>
2.2 使用 URL 路由
通过创建一个包含主页、关于页面和联系页面的小网站来学习路由。传统的静态 HTML 网站会将这些内容结构化为三个单独的 HTML 文件,但使用 Angular 路由系统可以将这些页面注入到单个容器或父视图页面中。
定义路由时,核心是
$route
服务,它允许创建 URL 和视图文件名之间的映射。例如:
$routeProvider.when('/about', {
templateUrl: 'pages/about.html',
controller: 'aboutController'
});
这个路由表示当 URL 的路径为
/about
时,加载视图模板
pages/about.html
,并使用
aboutController
。
下面是一个更完整的示例,展示了如何配置路由:
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"/>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css"/>
<script src="angular.min.js"></script>
<script src="angular-route.js"></script>
<script>
var app = angular.module('app', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'pages/home.html',
controller: 'homeController'
})
.when('/pages/about', {
templateUrl: 'pages/about.html',
controller: 'aboutController'
})
.when('/pages/contact/', {
templateUrl: 'pages/contact.html',
controller: 'contactController'
})
.otherwise({
templateUrl: 'pages/routeNotFound.html',
controller: 'notFoundController'
});
});
app.controller('homeController', function ($scope) {
$scope.message = 'Welcome to my home page!';
});
app.controller('aboutController', function ($scope) {
$scope.message = 'Find out more about me.';
});
app.controller('contactController', function ($scope) {
$scope.message = 'Contact us!';
});
app.controller('notFoundController', function ($scope) {
$scope.message = 'There seems to be a problem finding the page you wanted';
$scope.attemptedPath = $location.path();
});
</script>
</head>
<body ng-controller="homeController">
<header>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">My Website</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><a href="#"><i class="fa fa-home"></i> Home</a></li>
<li><a href="#about"><i class="fa fa-shield"></i> About</a></li>
<li><a href="#contact"><i class="fa fa-comment"></i> Contact</a></li>
</ul>
</div>
</nav>
</header>
<div id="main">
<div ng-view></div>
</div>
</body>
</html>
在这个示例中,我们配置了四个路由:主页、关于页面、联系页面和路由未找到页面。每个路由都指定了对应的视图模板和控制器。
下面是不同 URL 下
$location
服务的方法表现:
| URL | $location.path() | $location.url() | $location.absUrl() |
| — | — | — | — |
|
http://localhost:63342/index.html#/
|
/
|
/
|
http://localhost:63342/index.html#/
|
|
http://localhost:63342/index.html#/about
|
/about
|
/about
|
http://localhost:63342/index.html#/about
|
|
http://localhost:63342/index.html#/contact?someParam=someValue
|
/contact
|
/contact?someParam=someValue
|
http://localhost:63342/index.html#/contact?someParam=someValue
|
路由系统通过比较
$location.path()
的值和路由定义来确定加载哪个视图模板。当用户与导航链接交互时,当前路由会发生变化,从而加载不同的视图。
graph LR
A[用户访问 URL] --> B{匹配路由}
B -->|匹配成功| C[加载对应视图模板]
B -->|匹配失败| D[加载 routeNotFound.html]
3. 视图模板
以下是四个视图模板的代码:
<!-- 主页 -->
<div class="jumbotron text-center">
<h1>Home Page</h1>
<p>{{ message }}</p>
<div>
</div>
</div>
<!-- 关于页面 -->
<div class="jumbotron text-center">
<h1>About Page</h1>
<p>{{ message }}</p>
<div>
</div>
</div>
<!-- 联系页面 -->
<div class="jumbotron text-center">
<h1>Contact Page</h1>
<p>{{ message }}</p>
<div>
</div>
</div>
<!-- 路由未找到页面 -->
<div class="jumbotron text-center">
<h1>This is not good</h1>
<p>{{message}}</p>
<p class="has-error">{{attemptedPath}}</p>
</div>
这些视图模板使用了 Bootstrap 定义的类来帮助布局。在路由未找到页面中,使用了
has-error
类将尝试的路径标记为红色,以突出错误输入。
4. 控制器
为每个路由定义指定了控制器,除了最后一个控制器,其他控制器只是设置了
$scope.message
的值,以便区分不同页面。
app.controller('homeController', function ($scope) {
$scope.message = 'Welcome to my home page!';
});
app.controller('aboutController', function ($scope) {
$scope.message = 'Find out more about me.';
});
app.controller('contactController', function ($scope) {
$scope.message = 'Contact us!';
});
在配置路由时,需要注意以下几点:
- 声明依赖
ngRoute
模块,否则路由系统无法正常工作。
- 使用应用模块的
config()
方法设置路由配置,该方法只能使用
$routeProvider
而不是
$route
服务,因为
config()
方法比较特殊,只能使用提供者。
- 路由提供者的
when()
方法添加新的路由定义,注意路径的前向斜杠,不同的路径可能导致不同的匹配结果。
- 当无法匹配任何路由时,使用
otherwise()
方法显示路由未找到页面。
通过以上的步骤和示例,我们可以看到如何使用 AngularJS 的服务、服务器通信和路由系统来构建一个功能强大且易于管理的单页应用。
AngularJS:服务、服务器通信与视图组织
5. 路由配置注意事项
在进行路由配置时,有一些重要的注意事项需要牢记,以确保路由系统的正常运行。
-
依赖声明
:创建应用模块时,必须声明对
ngRoute模块的依赖,否则路由系统将无法工作。示例代码如下:
var app = angular.module('app', ['ngRoute']);
-
config()方法与提供者 :使用应用模块的config()方法来设置路由配置,此方法只能使用提供者,而不是服务。所以要使用$routeProvider来配置路由。例如:
app.config(function ($routeProvider) {
// 配置路由
$routeProvider
.when('/', {
templateUrl: 'pages/home.html',
controller: 'homeController'
})
.when('/pages/about', {
templateUrl: 'pages/about.html',
controller: 'aboutController'
})
.when('/pages/contact/', {
templateUrl: 'pages/contact.html',
controller: 'contactController'
})
.otherwise({
templateUrl: 'pages/routeNotFound.html',
controller: 'notFoundController'
});
});
-
when()方法路径注意 :routeProvider的when()方法用于添加新的路由定义,路径中的前向斜杠非常重要。例如,/pages/about和pages/about是不同的路径,缺少前向斜杠可能会在导航网站时导致Not found错误。 -
otherwise()方法的使用 :当无法匹配任何路由时,使用otherwise()方法显示路由未找到页面,以提供更好的用户体验。
6. 路由系统工作流程总结
下面通过一个 mermaid 流程图更直观地展示路由系统的工作流程:
graph LR
A[用户访问网站] --> B[加载 index.html]
B --> C{用户点击导航链接}
C -->|是| D[更新 $location.path() 值]
C -->|否| B
D --> E{匹配路由}
E -->|匹配成功| F[加载对应视图模板和控制器]
E -->|匹配失败| G[加载 routeNotFound.html 和 notFoundController]
F --> H[更新页面内容]
G --> H
从流程图可以看出,用户访问网站首先加载
index.html
,当用户点击导航链接时,
$location.path()
的值会更新,路由系统会根据这个值去匹配路由。如果匹配成功,就加载对应的视图模板和控制器,并更新页面内容;如果匹配失败,则加载路由未找到页面。
7. 实际应用中的考虑
在实际应用中,除了上述的基本配置和流程,还需要考虑以下方面:
- 错误处理的优化 :目前的错误处理代码只是简单地显示错误信息,在实际应用中,可以根据不同的错误类型提供更详细的错误提示和解决方案,以提高用户体验。例如,可以根据不同的 HTTP 状态码显示不同的错误信息:
promise.error(function (data, status) {
if (status === 404) {
$scope.errorMessage = "请求的页面不存在,请检查 URL。";
} else if (status === 500) {
$scope.errorMessage = "服务器内部错误,请稍后再试。";
} else if (status === 0) {
$scope.errorMessage = "网络或 HTTP 级别问题,请检查网络连接。";
} else {
$scope.errorMessage = "响应 HTTP 状态是 " + status;
}
$scope.showErrorMessage = true;
});
- 路由参数的使用 :在实际应用中,可能需要传递参数到路由中。例如,在一个博客网站中,可能需要根据文章的 ID 来显示具体的文章内容。可以在路由配置中使用参数,示例如下:
$routeProvider.when('/article/:articleId', {
templateUrl: 'pages/article.html',
controller: 'articleController'
});
在控制器中可以通过
$routeParams
来获取参数:
app.controller('articleController', function ($scope, $routeParams) {
$scope.articleId = $routeParams.articleId;
// 根据 articleId 获取文章内容
});
- 性能优化 :随着应用的增长,可能会有大量的视图模板和控制器,这会影响应用的性能。可以采用懒加载的方式,只在需要时加载视图模板和控制器,以减少初始加载时间。
总结
AngularJS 的服务、服务器通信和路由系统为构建单页应用提供了强大的功能。通过合理使用这些功能,可以将复杂的逻辑从模型和视图逻辑中分离出来,提高代码的可维护性和可扩展性。在实际应用中,需要注意路由配置的细节,优化错误处理,合理使用路由参数,并考虑性能优化等方面,以构建出高效、稳定且用户体验良好的单页应用。
通过以下表格总结本文的主要内容:
| 主题 | 主要内容 |
| — | — |
| 服务与服务器通信 | 处理异步通信时,使用
promise
对象的
finally
方法处理通用任务;通过
success
方法处理返回数据,
error
方法处理错误 |
| 组织视图 | 安装
ngRoute
模块,使用
$route
服务定义 URL 和视图文件名的映射,通过
ngView
指令加载视图模板 |
| 路由配置注意事项 | 声明
ngRoute
依赖,使用
$routeProvider
在
config()
方法中配置路由,注意路径的前向斜杠和
otherwise()
方法的使用 |
| 实际应用考虑 | 优化错误处理,使用路由参数,进行性能优化 |
希望通过本文的介绍,你对 AngularJS 的服务、服务器通信和路由系统有了更深入的理解,并能够运用这些知识构建出优秀的单页应用。
超级会员免费看
59

被折叠的 条评论
为什么被折叠?



