基于AngularJS实现iOS8自带的计算器(2)

$scope.init=function(){ $scope.num=[]; $scope.opt=[]; $scope.history=[]; $scope.flag = true; $scope.isOpt=true; } ; $scope.showResult=function(a){ $scope.history.push(a); var reg=https://www.jb51.net/\d/ig,regDot=https://www.jb51.net/\./ig,regAbs=https://www.jb51.net/\//ig; //如果点击的是个数字 if(reg.test(a)) { //消除冻结 if($scope.isOpt==false){ $scope.isOpt=true; } if ($scope.result != 0 && $scope.flag && $scope.result != "error") { $scope.result += a; } else { $scope.result = a; $scope.flag = true; } }

init方法是用来初始化一些变量和标志,让它们回到原始状态。showResult方法是显示界面响应用户操作的主方法,上面的代码是该方法中的一个if分支,表示如果输入的是一个数字,那么如果对运算符的输入已经被冻结(当前不允许输入运算符了,输入后会被忽略),那么输入数字的时候,就解开冻结状态,以便下次输入运算符的时候会进入运算符栈。如果当前显示的结果不为空并且现在按下的数字是当前显示的数字的一部分并且没有发生错误,那么显示的结果就是当前按下的数字接在当前显示数字的末尾,否则就代表重新显示,重新显示的时候需要让下次再输入的数字接在这个数字后面显示。

js代码(接上)

//如果点击的是AC else if(a=="AC"){ $scope.result=0; $scope.init(); }

如果点击的是AC,那么代表初始化,让显示结果为0,清空所有状态。

js代码(接上)

//如果点击的是个小数点 else if(a=="."){ if($scope.result!=""&&!regDot.test($scope.result)){ $scope.result+=a; } }

如果点击的是个小数点,则在当前显示不为空并且当前显示的结果里面不存在小数点的情况下让这个小数点接在当前显示的末尾。

js代码(接上)

//如果点击的是个取反操作符 else if(regAbs.test(a)){ if($scope.result>0){ $scope.result="-"+$scope.result; } else{ $scope.result=Math.abs($scope.result); } }

如果点击的是个取反操作,则将当前显示结果取反

js代码(接上)

//如果点击的是个百分号 else if(a=="%"){ $scope.result=$scope.format(Number($scope.result)/100); }

如果点击的是个百分号,则将当前显示结果除以100之后再显示,这里有个format函数

其代码如下:

//格式化result输出 $scope.format=function(num){ var regNum=https://www.jb51.net/.{10,}/ig; if(regNum.test(num)){ if(/\./.test(num)){ return num.toExponential(3); } else{ return num.toExponential(); } } else{ return num; } }

它的作用主要是ios8自带的计算器不会无限显示很多位的数字,如果超过10位(包括小数点),则采用科学计算法来显示,这里为了简便,对于含有小数点且超过10位的显示结果采用科学计算法计算的时候,让它保留小数点之后3位显示。

js代码(showResult部分接上)

//如果点击的是个运算符且当前显示结果不为空和error else if($scope.checkOperator(a)&&$scope.result!=""&&$scope.result!="error"&&$scope.isOpt){ $scope.flag=false; $scope.num.push($scope.result); $scope.operation(a); //点击一次运算符之后需要将再次点击运算符的情况忽略掉 $scope.isOpt=false; }

这个分支是最复杂的一个分支,它代表如果输入的是一个运算符,那么就要进行运算了。进入到这个分支,需要首先将flag置为false,作用是下次再输入数字就是重新输入数字而不是接着当前显示结果输入了。

然后要让当前显示的数字作为被运算的数字首先进入到数字栈中,operation方法就是运算方法,因为这次已经点击了一个运算符,所以下次再点击就要忽略这个运算符,将isOpt置为false。

operation代码如下

//比较当前输入的运算符和运算符栈栈顶运算符的优先级 //如果栈顶运算符优先级小,则将当前运算符进栈,并且不计算, //否则栈顶运算符出栈,且数字栈连续出栈两个元素,进行计算 //然后将当前运算符进栈。 $scope.operation=function(current){ //如果运算符栈为空,直接将当前运算符入栈 if(!$scope.opt.length){ $scope.opt.push(current); return; } var operator,right,left; var lastOpt=$scope.opt[$scope.opt.length-1]; //如果当前运算符优先级大于last运算符,仅进栈 if($scope.isPri(current,lastOpt)){ $scope.opt.push(current); } else{ operator=$scope.opt.pop(); right=$scope.num.pop(); left=$scope.num.pop(); $scope.calculate(left,operator,right); $scope.operation(current); } };

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzjpdw.html