用AngularJS和Firebase制作一个实时投票应用
发布在用Angular开发web应用2014年3月12日view:20511
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

enter image description here

用AngularJS和Firebase制作一个实时投票应用

如果你是iOS系统的fen’si粉丝,那么在快要结束的这一天,你起床后的第一件事情肯定是拿出手机升级最新发布的ios7.1系统。关于ios系统要聊的东西当然很多,但是我们今天的主题不是这个,但确和今天刚发布的系统有着不小的联系。

今天苹果公司在发布ios7.1系统时,一个网站在线上挂出了一个投票系统,供果粉们为新发布的系统进行投票。如果你还没看过这个投票系统的话,它的链接是:http://www.polarb.com/publishers/results/poll_sets/2042。这个投票系统和一般的投票系统有所不同,它是一个实时投票系统,实时是一个什么概念,具体到上面这个ios投票系统上来说,就是当有人对一个项目进行投票时,页面都会进行实时响应(在这个投票系统中具体表现为数字的增加和背景色发生闪动)。这真是太酷了!

其实实时应用并不是什么新鲜的玩意,我们在日常生活中一直都在享受实时给我们带来的便利,比如QQ,微信,或者前端时间非常流行的你画我猜,这些东西的背后都有实时系统在进行支撑。具体到web框架上,近两年来炒的火热的Meteor,Sails框架都是以实时性作为其主要特色进行宣传。当然,前面提到的框架都是好东西,但是从开始学习到真正投入使用之间可能需要花费不少时间和精力,又没有一种省事省力的东西能让我们以最快的时间编写一个实时应用呢?

还好我们有Firebase。简单来说,Firebase是一个提供实时数据的云服务平台,你只需要将你的数据存放在Firebase上,就可以通过它提供的接口来实现实时数据同步。举个例子,就像前面的投票系统一样,两个人在不同的电脑上打开了同一个网页,其中一个人在网页上进行了操作,网页上产生的变化就会实时在另一个人的网页上表现出来。在Firebase中,我们可以选择我们熟悉的语言来创建实时应用,其中就有前端工程师最熟悉的JavaScript,包括浏览器端的JS和服务器端的Node。更重要的是,它非常非常的简单,相信在半小时以内,你一定可以用创建一个你自己的实时应用。

如果你喜欢AngularJS,还有一个好消息就是Firebase针对于AngularJS特别提供了一个特别的模块叫做Angularfire,其中提供了$firebase service,通过几个简单的接口,我们就可以轻松的创建强大的实时应用。Angular的数据绑定结合服务器端的数据实时同步,想想就有些小激动呢!顺便提一句,Firebase的网站采用的就是AngularJS框架,难怪Firebase对于AngularJS情有独钟。

正如标题所说的,我们今天的任务就是使用AngularJS和firebase来创建一个类似于ios7投票系统的实时投票系统。第一步当然是注册一个firebase的账户,过程非常简单在这里就不具体说了,要特别提到的一点是,firebase虽然是一个收费的云服务平台,但是它非常贴心的提供了一个hack plan,可以让我们免费体验firebase的强大功能,只是在功能方面有所限制,但是对于实时的体验却完全没有打折扣。现在你应该已经申请好了一个firebase账户,一开始我们需要在dashboard中创建一个新的APP,如下图所示:

#图1

在这里,我们创建的这个APP叫做ios-vote,输入你想要的NAME和URL,点击下面的蓝色按钮就行,默认情况下,NAME和URL相同,当然你可以修改成为自己喜欢的名称。创建好了APP以后,我们看到的这个样子:

#图2

现在我们需要往这个APP中输入一些初始数据为我们所用,点击下面的蓝色按钮View Firebase进入数据管理界面。如图所示:

#图3

默认情况下,你会看到一个和APP名称相同的数据集,在这里,我们的APP名称叫做IOS-VOTE,而这个默认的数据集叫做ios-vote,名称一样,只是大写变成了小写。现在我们就往这个数据集里面输入一点我们需要的数据,我们分别输入三个数据:option1,option2,以及loaded,并分别将它们初始化。如图所示:

#图4

既然我们已经在我们的数据集中输入了一些初始化数据,现在我们就能开始着手创建我们的应用了。首先,我们需要在HTML页面中引入angular,angularfire,firebase这几个JS文件,为了能够进行背景色的变化,我们还需要引入jQuery和一个用于控制颜色变化的jQuery插件jquery-color-animate。如下所示:

<script type="text/javascript" charset="utf-8" src='./jquery.js'></script>
<script type="text/javascript" charset="utf-8" src='./jquery.animate-colors-min.js'></script>
<script src='./angular.js'></script>
<script src='https://cdn.firebase.com/v0/firebase.js'></script>
<script src='https://cdn.firebase.com/libs/angularfire/0.7.0/angularfire.min.js'></script>  

引入了JS文件之后,我们就要开始编写我们的HTML结构了,具体的HTML结构非常简单,只需要两个button标签即可,我在上面添加了一些部分,于是HTML部分如下:

<body ng-app='iosvote'>
    <div id='container' ng-controller='ivote'>
          <div id='panel'>
            <div id='title'><h2>你觉得张小俊是帅哥吗?</h2></div>
            <button id='yes' {{vote.yes}} ng-click='voteOptionOne()' class='btn btn-info'>是: {{vote.option1}} 票</button>
            <button id='no' ng-click='voteOptionTwo()' class='btn btn-info'>不是: {{vote.option2}} 票</button>
          </div>
    </div>
  </body>

在这里,我们非常简单的使用了一个ng-app指令以及一个ng-controller指令,以及两个花括号数据绑定,非常简单。

接下来,我们要编写JS的逻辑部分,我们先把全部代码放上来,再讲其中的重要部分:

var app = angular.module('iosvote',['firebase']);
           app.controller('ivote',['$scope','$firebase','$log',function($scope,$firebase){
                var ref = new Firebase("https://ios-vote.firebaseIO.com");
                $scope.yes = 'disabled';
                $scope.vote = $firebase(ref);
                $scope.vote.option1 = $scope.vote.option1;
                $scope.vote.option2 = $scope.vote.option2;
                $scope.voteOptionOne = function(){
                  $scope.vote.option1 = $scope.vote.option1+1;
                  if($scope.vote.loaded){
                  $scope.vote.$save('option1');
                  }
                };
                $scope.voteOptionTwo = function(){
                  $scope.vote.option2 = $scope.vote.option2+1;
                  if($scope.vote.loaded){
                  $scope.vote.$save('option2');
                  }
                };
                $scope.vote.$on('change',function(){
                  $('#panel').animate({backgroundColor: "#F9D56E"}).animate({backgroundColor: "#FAFAFA"});
                });
           }]);

这里需要具体讲述的有几个地方,首先,我们通过new操作符实例化了一个我们在前面创建的APP的实例,注意构造器函数Firebase的参数,它就是我们创建的APP的地址。

其次,我们在实例化Angular模块的时候,引入了firebase模块,因为我们要使用其中的$firebase service,你会在controller的依赖注入中看到$firebase。

接下来,我们通过将这个Firebase的实例传递给$firebase service来提取其中的数据,并将它赋值给$scope.vote,现在的$scope.vote中就包含我们在前面初始化的option1,option2以及loaded数据的值。

然后,我们要响应按钮的点击事件,于是在voteOptionOne和voteOptionTwo函数中,我们首先将$scope.option1和$scope.option2分别加1,在使用firebase为我们提供的$save方法将数据同步到云端,这时,Firebase的实时性就体现出来了,只要云端的数据发生变化,所有与之连接的客户端数据也会相应的发生同步,因此这时,所有连接着云端的投票页面数据都会相应添加1。

最后,我们想要给每次点击添加上背景色闪动的效果,于是我们使用$on方法来监听$scope.vote的数据change事件,只要是云端的数据发生了变化,背景色就会发生闪动。

完整的代码如下所示:

<html>
  <head>
    <title>模仿ios实时投票</title>
    <meta charset='utf-8'>
    <meta name="viewport" id="viewport" content="width=device-width, initial-scale=1">
    <meta name='author' content='张小俊128'>
    <meta name='keywords' content='ios7.1 实时 angularjs firebase'>
    <meta name='description' content='该应用使用angular和firebase实现了类似于ios7.1的实时投票功能'>
    <script type="text/javascript" charset="utf-8" src='./jquery.js'></script>
    <script type="text/javascript" charset="utf-8" src='./jquery.animate-colors-min.js'></script>
    <script src='./angular.js'></script>
    <script src='https://cdn.firebase.com/v0/firebase.js'></script>
    <script src='https://cdn.firebase.com/libs/angularfire/0.7.0/angularfire.min.js'></script>
    <style>
      *{
        margin: 0px;
        padding: 0px;
      }
      #container{
        width: 100%;
        height: 100%;

      }
      #panel{
        position:absolute;
        width:500px;
        height:300px;
        top:200px;
        left:50%;
        margin-left: -250px;
        -webkit-border-radius: 5px;
        -webkit-box-shadow: 0px 0px 5px #131314;
      }
      #title{
        position: absolute;
        width:450px;
        top:30px;
        left:25px;
      }
      #title img{
        display:block;
        width:150px;
        height:150px;
        position: absolute;
        top:
      }
      #title h2{
        position: absolute;
        width:300px;
        left: 160px;
        top: 70px;
      }
      #yes{
        position: absolute;
        bottom: 50px;
        left: 200px;
        disabled: true;
      }
      #no{
        position: absolute;
        bottom: 50px;
        left: 280px;
      }
    </style>
</head>
  <body ng-app='iosvote'>
    <div id='container' ng-controller='ivote'>
          <div id='panel'>
            <div id='title'><h2>你觉得张小俊是帅哥吗?</h2></div>
            <button id='yes' {{vote.yes}} ng-click='voteOptionOne()' class='btn btn-info'>是: {{vote.option1}} 票</button>
            <button id='no' ng-click='voteOptionTwo()' class='btn btn-info'>不是: {{vote.option2}} 票</button>
          </div>
    </div>
    <script type="text/javascript" charset="utf-8">
       var app = angular.module('iosvote',['firebase']);
           app.controller('ivote',['$scope','$firebase','$log',function($scope,$firebase){
                var ref = new Firebase("https://ios-vote.firebaseIO.com");
                $scope.yes = 'disabled';
                $scope.vote = $firebase(ref);
                $scope.vote.option1 = $scope.vote.option1;
                $scope.vote.option2 = $scope.vote.option2;
                $scope.voteOptionOne = function(){
                  $scope.vote.option1 = $scope.vote.option1+1;
                  if($scope.vote.loaded){
                  $scope.vote.$save('option1');
                  }
                };
                $scope.voteOptionTwo = function(){
                  $scope.vote.option2 = $scope.vote.option2+1;
                  if($scope.vote.loaded){
                  $scope.vote.$save('option2');
                  }
                };
                $scope.vote.$on('change',function(){
                  $('#panel').animate({backgroundColor: "#F9D56E"}).animate({backgroundColor: "#FAFAFA"});
                });
           }]);
    </script>
  </body>
</html>

是不是非常非常简单!还要提到的一点是,Firefox还为我们提供了静态资源host服务,我们只需要使用npm安装firebase-tools模块,就可以将静态资源部署到Firebase提供的云上,非常方便。于是,你可以在https://ios-vote.firebaseapp.com/看到我们在上面创建的这个应用,如下所示:

#图5

Firebase非常强大,我们可以花费少量的时间来创建强大的实时应用,更重要的是由于我们无需去考虑服务器端数据的问题,我们可以将更多的精力放在前端逻辑的编写上,这对于前端工作者来说绝对是一个好消息。Firebase还提供了很多强大的接口和功能,等待我们去探索。实践是最好的老师,只有不断练习才能有所进步,同时也欢迎大家到前面提到的页面为我投票。


如果你觉得本文对你有帮助,请为我提供赞助 https://me.alipay.com/jabez128

评论
发表评论
3年前
添加了一枚【评注】:这个挺好的
3年前
添加了一枚【评注】:这是什么插件
4年前

帅呆了

4年前

编写好了html文件 怎么把它部署到云上去啊

WRITTEN BY
张小俊128
Intern in Baidu mobile search department。认真工作,努力钻研,期待未来更多可能。
TA的新浪微博
PUBLISHED IN
用Angular开发web应用

讲述Angular开发框架的基础知识,帮助读者快速学习并深入理解Angular的开发理念和具体应用方式

我的收藏