• 用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」:

  • 相关阅读:
    HDU
    Count on a tree
    Codeforces Round #368 (Div. 2) D. Persistent Bookcase
    Codeforces Round #321 (Div. 2) E
    Codeforces Round #220 (Div. 2) D
    树状数组区间加法更新板子
    在 tableview的上面 添加 一个view, 下面 加一个 button,都是 监听 scrollview的滑动而已,
    synchronize,
    菊花,
    4294967295,
  • 原文地址:https://www.cnblogs.com/branton-design/p/5900012.html
Copyright © 2020-2023  润新知