用AngularJs制作单页面应用

在我的 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」:

原文地址:https://www.cnblogs.com/branton-design/p/5900012.html