首先创建angularjs的基本项目就不说了,最好是利用yeoman这个脚手架工具直接生成,如果没有该环境的,当然也可以通过自行下载angularjs的文件引入项目。
实例详解
main.js是项目的主要js文件,所有的js都写在这个文件中,初始化之后,该文件的js代码如下
angular .module('calculatorApp', [ 'ngAnimate', 'ngCookies', 'ngResource', 'ngRoute', 'ngSanitize', 'ngTouch' ]) .controller('MainCtrl', function ($scope) { $scope.result=""; $scope.data={ "1":["AC","+/-","%","÷"], "2":["7","8","9","×"], "3":["4","5","6","-"], "4":["1","2","3","+"], "5":["0",".","="] }; });
这里的result是用来双向绑定显示运算结果的,data为计算器键盘上的数字和符号。
该项目相关的所有css代码如下:
*{ margin:0; padding:0; } body { padding-top: 20px; padding-bottom: 20px; } h1{ text-align:center; color:#3385ff; } .main{ margin:20px auto; border:1px solid #202020; border-bottom: none; width:60%; height:600px; } .result{ display: block; width: 100%; height: 30%; background:#202020; box-sizing: border-box; border:none; padding: 0; margin: 0; resize: none; color: #fff; font-size: 80px; text-align: right; line-height: 270px; overflow: hidden; background-clip: border-box; } .row{ height: 14%; background: #d7d8da; box-sizing: border-box; border-bottom: 1px solid #202020; overflow: hidden; } .col{ height: 100%; box-sizing: border-box; border-right:1px solid #202020; float: left; color: #202020; font-size: 28px; text-align: center; line-height: 83px; } .normal{ width: 25%; } .end-no{ width: 25%; border-right: none; background: #f78e11; color: #fff; } .zero{ width: 50%; } .history{ background:#3385ff ; color:#fff; font-size: 22px; text-align: center; }
然后是html的布局如下:
<body ng-app="calculatorApp" > <h1>calculator for ios8</h1> <hr/> <p>{{ history.join(" ") }}</p> <div> <textarea ng-model="result" ></textarea> <div ng-repeat="item in data"> <div ng-repeat="a in item" ng-class="showClass($index,a)" ng-click="showResult(a)">{{ a }}</div> </div> </div> </body>
这里class为history的p标签是用来显示输入记录的,就是说你按下的所有键都会显示在上面,便于查看结果,history为当前scope下面的一个数组,后面会讲解。这里使用一个textarea来作为计算结果的显示屏幕,主要是为了使用双向绑定的特性。同时生成计算器各个按键和界面元素都是通过对data对象进行 循环遍历来生成的,showClass方法是scope下面的一个方法,用来获取不规则界面显示元素的class属性,后面会讲解,showResult方法就是对按键响应的主方法,我们所有对按键的按下响应都是通过这个方法来的,后面会详细讲解。
showClass方法代码如下:
//显示计算器样式 $scope.showClass=function(index,a){ if(a==0){ return "zero"; } return index==3||a=="="?"end-no":"normal"; };
这个方法主要是针对每行的最后一列要显示为橘黄色和对于显示0的按键要占用两个单元格来进行特殊处理。
到目前为止,已经完全实现了计算器的界面
效果图如下:
下面需要实现对按键的响应,按键包括数字键,运算符键,AC键,每种按键按下都会有不同相应并且按键之间是存在联系的
为了使代码容易讲解,采用分段性给出showResult方法的代码然后进行详细解释的方法。
首先,这里要添加几个变量进行控制和存储之用。
//计算时用的数字的栈 $scope.num=[]; $scope.history=[]; //接受输入用的运算符栈 $scope.opt=[]; //计算器计算结果 $scope.result=""; //表示是否要重新开始显示,为true表示不重新显示,false表示要清空当前输出重新显示数字 $scope.flag=true; //表示当前是否可以再输入运算符,如果可以为true,否则为false $scope.isOpt=true;
num数组实际上是一个栈,用来接收用户输入的数字,具体用法后面会讲解,history数组为用户输入的所有按键,每次按下就让该按键上的符号或数字进栈,然后使用绑定实时显示在界面上。opt数组是另外一个栈,用来接收用户输入的运算符。具体用法后面会讲解,flag是一个标志,为true的时候表示在按下数字的过程中被按下的数字是当前显示数字的一部分,需要跟在其后面显示,比如当前界面显示的是12,再按下3的时候会判断该标志,如果为true,就显示123,否则就清空界面,直接显示3.isOpt是另外一个标志,主要是为了防止用户在输入过程中对运算符的非法输入,比如说用户接连输入了1+2+,当输到这里是,下面输入的应该是一个数字,但是用户却输入了一个运算符,通过判断这个标志,会让计算器忽略这个非法的运算符,让输入依然保持1+2+。
下面的代码分段给出,完整的代码就是将它们连接起来。