今天以 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-width: 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」: