在我的 GitHub 项目 Remote Camera 中,我使用了 AngularJs 来完成一个 Web App 的开发,感觉挺方便挺赞的。
今天以 Remote Camera 为例子,分享下如何实现。
一、需求功能
首先我为 Remote Camera 做了功能规划,明确有几个点:
- 控制用户访问的登录功能(login)
- 核心的拍照功能(camera)
- 相片集的展示和删除功能(photos)
- 动态获取路由器 IP 地址功能(address)
作为用户角度来看,大致的流程可以理解为:
页面刷新打开登录界面,登录完成之后到了一个菜单界面(menu);在菜单页面,将作为功能入口,分别进入是拍照页面、相片管理页面、IP地址页面。
二、设计与思路
基于 Remote Camera 的需求和功能,如果用户没有登录,则调回到默认的登录界面;登录成功之后,进入菜单页面,随后可以通过菜单入口进入其他功能区域。
简单的设计流程如下图,请注意 URL
的变化:
而具体到页面,最终的 WebApp 就只有一个 HTML(作为iwer)和 Camera.js(主要用来Router和Controller),而数据则来源于后端运行 NodeJs。
三、AngularJs 的引入和 Viewer 的实现
在 HTML
就像引入普通的 JS 一样引入 AngularJs
。同时,定义好应用的名称,以及视图的位置(这里可能得有 AngularJs 的基础)。
<!doctype html>
<-- //定义好 ng-app 作为应用的名称 -->
<html ng-app="RemoteCamera">
<head>
<meta charset="utf-8">
<title>Remote Camera</title>
<script type="text/javascript">
// 用于登录状态的标识
connected = {{alreadyLogged}};
</script>
<-- //AngularJs 的引入 -->
<script src="script/angular.min.js"></script>
<script src="script/angular-resource.min.js"></script>
<script src="script/camera.js"></script>
</head>
<-- //定义好 ng-view -->
<body ng-view>
<-- //这里是 viewer 代码 -->
</body>
</html>
每一个 Viwer 都会在 Camera.js
中对应一个 Controller
来渲染,所以有两部分,第一部分是 HTML 中的模板:
<-- //login view -->
<script type="text/ng-template" id="loginView">
<div class="container" ng-controller="loginCtrl" >
//这里是具体的HTML代码
</div>
</script>
<-- //camera view -->
<script type="text/ng-template" id="cameraView">
<div class="container" ng-controller="cameraCtrl" >
//这里是具体的HTML代码
</div>
</script>
<-- //photos view -->
<script type="text/ng-template" id="photosView">
<div class="container" ng-controller="photosCtrl" >
//这里是具体的HTML代码
</div>
</script>
另外一部分,则是使用了 AngularJs 中的 $routeProvider
来进行路由跳转,这样就能控制访问的 URL
与对应的 View
正确显示:
/**
* @路由把 HTML 中的 View 和 AngularJs 中的 Controller 对应起来
* @当访问「/」的时候,就会显示「登录(login)」
* @登录成功则跳转到「菜单(menu)」
* @访问非定义的内容,也会跳到「/」
*/
var remoteCamera = angular.module('RemoteCamera',['ngResource'])
.config(function($routeProvider) {
$routeProvider.when("/", {
controller: remoteCamera.loginCtrl,
template: document.getElementById('loginView').text
}).when("/menu", {
controller: remoteCamera.menuCtrl,
template: document.getElementById('menuView').text
}).when("/camera", {
controller: remoteCamera.cameraCtrl,
template: document.getElementById('cameraView').text
}).when("/photos", {
controller: remoteCamera.watchPhotosCtrl,
template: document.getElementById('photosView').text
}).otherwise({
redirectTo: "/"
})
});
四、AngularJs 中的 Controller 应用
在 View 中我们能看到对 Controller 这样的 ng-controller=loginCtrl
的定义,它将与 JS 中对应的 Controller 进行捆绑,数据间是双向绑定,同时作用于整个 DOM 结构。
而我们在 Controller 中,可以传递参数、可以和服务端进行交互、可以进行前端交互。那么,一个普通的 Controller 如下:
/**
* @定义登录的controller
*/
remoteCamera.controller('loginCtrl', function($scope, $resource, $location) {
//路由跳转,如果已经登录了,就调到「menu」
if(connected) {
return $location.path("/menu");
}
//定义的函数
$scope.doLogin = function() {
//与服务端的交互
$resource('/api/login').save({
//数据传递到服务器
}, function(data) {
//成功返回
console.log(data)
}, function() {
//错误返回
//与view的交互
$scope.errorMsg = 'Error';
});
};
})
总觉得还缺少点什么来的,还是直接看源代码吧, Camera.js 。
五、完善你的 WebApp
在 Remote Camera 中使用 AngularJs 来完成一个 WebApp,其实没多少代码和工作量。但要使它变成一个 WebApp,还需要完善一些细节。这里主要以 iOS 为例子。
接下来是为你的 WebApp 添加全屏、图标和初始界面:
<-- //加入响应式布局 -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<-- //设置safari的属性 -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Remote Camera" />
<-- //设置桌面图标 -->
<link rel="apple-touch-icon-precomposed" href="/images/54.jpg">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/images/72.jpg">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/images/114.jpg">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/images/144.jpg">
<-- //设置初始界面 -->
<link rel="apple-touch-startup-image" href="/images/start.jpg" />
<link rel="apple-touch-startup-image" href="/images/start.jpg" media="screen and (device- 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" />
六、遇到的问题
由于 HTML 页面是由 NodeJs 的 Swig 模板渲染出来,而 Swig 的参数语法又和 AngularJs 的语法一样,所以导致参数不能正常替换掉。于是,需要通过修改 AngularJs 的字符匹配来解决:
var myApp = angular.module('myApp', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
七、结篇
一篇文章并不能完整地阐述如何使用 AngularJs 来完成一个 WebApp,但基本的思路可以帮助你去完成。最后,展示一下「Remote Camera」的一些界面:
如果你也很感兴趣,欢迎「Star」或者「Fork」,有问题请提「Issues」: