Prefacio
En primer lugar, no hablemos de crear el proyecto básico de AngularJS. Es mejor usar la herramienta de andamio yeoman para generarla directamente. Si no existe dicho entorno, por supuesto, también puede presentar el proyecto descargando el archivo AngularJS usted mismo.
Explicación detallada de ejemplo
Main.js es el archivo JS principal del proyecto. Todos los JS están escritos en este archivo. Después de la inicialización, el código JS del archivo es el siguiente
angular .module ('calculatorApp', ['nganiMe', '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 ",", "," = "];El resultado aquí se utiliza para unir los resultados del cálculo en la unión de dos vías, y los datos son los números y símbolos en el teclado de la calculadora.
Todos los códigos CSS relacionados con este proyecto son los siguientes:
*{margen: 0; Pading: 0;} cuerpo {Padding-top: 20px; Bottom: 20px;} H1 {text-align: Center; Color:#3385ff;}. Main {Margen: 20px Auto; borde: 1px Solid #202020; Border-Bottom: Ninguno; Ancho: 60%; altura: 600px;}. resultado {pantalla: bloque; Ancho: 100%; Altura: 30%; Antecedentes:#202020; dimensionamiento de la caja: border-box; borde: ninguno; relleno: 0; margen: 0; cambiar el tamaño: ninguno; Color: #fff; tamaño de fuente: 80px; Text-Align: Right; Línea de altura: 270px; desbordamiento: oculto; Clip de fondo: border-box;}. fila {altura: 14%; Antecedentes: #d7d8da; dimensionamiento de la caja: border-box; Border-Bottom: 1px Solid #202020; desbordamiento: oculto;}. Col {altura: 100%; dimensionamiento de la caja: border-box; Border-Right: 1px Solid #202020; flotante: izquierda; Color: #202020; tamaño de fuente: 28px; Text-Align: Center; Línea-aguja: 83px;}. Normal {ancho: 25%;}. End-no {ancho: 25%; Border-Right: Ninguno; Antecedentes: #F78E11; color: #fff;}. Zero {ancho: 50%;}. Historia {fondo: #3385ff; Color: #fff; tamaño de fuente: 22px; Text-Align: Center;}Entonces el diseño HTML es el siguiente:
<Body ng-app = "calculatorApp"> <h1> Calculator para iOS8 </h1> <hr/> <p> {{History.Join ("")}} </p> <div> <xtexArea ng-model = "resultado"> </extArea> <div ng-repeat = "item in Data"> <div ng-speat = "A in ítem" a ítem " ng-class = "showclass ($ index, a)" ng-click = "showResult (a)"> {{a}} </div> </div> </div> </body> Aquí, la etiqueta P del historial de clases se usa para mostrar el registro de entrada, lo que significa que todas las teclas que presione se mostrarán en ella para ver fácilmente los resultados. La historia es una matriz debajo del alcance actual, que se explicará más adelante. Aquí se utiliza un TextAREA como la pantalla para los resultados del cálculo, principalmente para usar la función de enlace de dos vías. Al mismo tiempo, cada elemento clave e interfaz de la calculadora se generan en bucle sobre el objeto de datos. showClass es un método debajo del alcance, que se utiliza para obtener los atributos de clase de los elementos de visualización de la interfaz irregular. Se explicará más tarde. showResult es el método principal para responder a la clave. Todas nuestras respuestas a las claves se obtienen a través de este método, y explicaremos en detalle más adelante.
El código del método ShowClass es el siguiente:
// Mostrar estilo de calculadora $ scope.showclass = function (index, a) {if (a == 0) {return "cero"; } índice de retorno == 3 || a == "="? "End-no": "normal"; };Este método se ocupa principalmente de la última columna de cada fila que se mostrará como naranja y las teclas que muestran 0 deben ocupar dos celdas para un procesamiento especial.
Hasta ahora, la interfaz de la calculadora se ha implementado completamente
Las representaciones son las siguientes:
Lo siguiente debe realizar la respuesta a las claves. Las teclas incluyen teclas numéricas, teclas de operador y teclas de CA. Cada llave presiona tendrá diferentes respuestas y hay una conexión entre las teclas.
Para que el código sea más fácil de explicar, se utiliza un método para dar el código del método ShowResult en segmentos y luego explicarlo en detalle.
En primer lugar, necesitamos agregar varias variables para el control y el almacenamiento.
// La pila de números utilizados para el cálculo $ scope.num = []; $ scope.history = []; // La pila de operadores $ scope.opt = []; // El resultado del cálculo de la calculadora $ scope.result = ""; // El resultado de la calculadora $ scope.result = ""; // Significa si comenzar a mostrar nuevamente. Verdadero significa no volver a mostrar. Falso significa borrar la salida actual y volver a mostrar el número $ scope.flag = true; // Significa si el operador se puede ingresar ahora. Si puede ser verdadero, de lo contrario es falso $ scope.isopt = true;
La matriz NUM es en realidad una pila, utilizada para recibir los números ingresados por el usuario. El uso específico se explicará más adelante. La matriz de historial es todas las claves ingresadas por el usuario. Cada vez que lo presiona, los símbolos o números en la tecla se colocan en la pila, y luego se muestra en la interfaz en tiempo real utilizando el enlace. La matriz OPT es otra pila utilizada para recibir la entrada del operador por parte del usuario. El uso específico se explicará más adelante. La bandera es una bandera. Cuando es verdadero, significa que el número presionado durante la presentación del número es parte del número que se muestra actualmente y debe mostrarse detrás de él. Por ejemplo, la interfaz actual se muestra 12, y luego se juzgará Press 3. Si es cierto, se mostrarán 123. De lo contrario, la interfaz se borrará y 3.ISopt es otra bandera. Es principalmente para evitar que el usuario de la entrada ilegal de operadores durante el proceso de entrada. Por ejemplo, el usuario ingresa 1+ 2+ en sucesión. Cuando se ingresa la entrada aquí, la siguiente entrada debe ser un número, pero el usuario ingresa a un operador. Al juzgar esta bandera, la calculadora ignorará este operador ilegal y mantendrá la entrada aún 1+2+.
El siguiente código se proporciona en segmentos, y el código completo es conectarlos.
$ 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 = // d/ig, regdot = //./ig, regabs = /// ig; // Si hace clic en un número if (reg.test (a)) {// elimina el congelamiento 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; }} El método init se utiliza para inicializar algunas variables y banderas para devolverlas a su estado original. showResult es el método principal para mostrar la interfaz para responder a las operaciones del usuario. El código anterior es una rama IF en este método, lo que indica que si se ingresa la entrada del operador, entonces si la entrada al operador se ha congelado (el operador no se permite ingresar actualmente, y se ignorará después de la entrada), luego ingrese el número, el estado de congelación se desbloquea para que el pila de operadores se ingresará la próxima vez que se ingrese el operador se ingrese el operador. Si el resultado actualmente mostrado no está vacío y el número presionado es parte del número actualmente mostrado y no se produce ningún error, entonces el resultado mostrado es que el número presionado actualmente está conectado al final del número que se muestra actualmente. De lo contrario, significa que el número que ingresa la próxima vez debe mostrarse después de este número al volver a mostrar.
Código JS (continuación)
// Si hace clic en AC Else if (a == "AC") {$ Scope.Result = 0; $ scope.init (); }Si el AC haciendo clic, significa inicialización, deje que el resultado de la pantalla sea 0, y todos los estados se borren.
Código JS (continuación)
// Si hace clic en un punto decimal si (a == ".") {If ($ scope.result! = "" "&&! Regdot.test ($ scope.result)) {$ scope.result+= a; }}Si el hecho es un punto decimal, deje que el punto decimal se conecte al final de la pantalla actual si la pantalla actual no está vacía y no hay un punto decimal en el resultado de la pantalla actual.
Código JS (continuación)
// Si hace clic en un operador inverso si (regabs.test (a)) {if ($ scope.result> 0) {$ scope.result = "-"+$ scope.result; } else {$ scope.result = math.abs ($ scope.result); }}Si el clic es una operación inversa, el resultado de la pantalla actual será inversamente
Código JS (continuación)
// Si hace clic en un signo porcentual si (a == "%") {$ scope.result = $ scope.format (número ($ scope.result)/100); } Si hace clic en un signo porcentual, divida el resultado actual mostrado por 100 y luego muestralo. Aquí hay una función format
El código es el siguiente:
// Formato de resultado resultado $ scope.format = function (num) {var regnum =/. {10,}/ig; if (regnum.test (num)) {if (//./. test (num)) {return num.toexponential (3); } else {return num.ToEesponential (); }} else {return num; }}} else {return num; }}Su función principal es que la calculadora que viene con iOS8 no mostrará muchos dígitos infinitamente. Si excede los 10 dígitos (incluidos los puntos decimales), se utilizarán cálculos científicos para mostrar. Para simplificar, al usar cálculos científicos para resultados de visualización que contienen puntos decimales y superan los 10 dígitos, permita que retiene la visualización de 3 dígitos después del punto decimal.
El código JS (la parte showResult está conectada)
// Si el operador hecho hecho y el resultado de la pantalla actual no están vacíos y Error de lo contrario if ($ scope.checkoperator (a) && $ scope.result! = "" && $ scope.result! = "Error" && $ scope.isopt) {$ scope.flag = false; $ scope.num.push ($ scope.result); $ scope.operation (a); // Después de hacer clic en el operador una vez, debe ignorar la situación en la que se hace clic nuevamente en el operador. $ scope.isopt = false; }Esta rama es la rama más compleja, lo que significa que si la entrada es un operador, entonces se debe realizar la operación. Para ingresar a esta rama, debe establecer el indicador en falso primero, que es ingresar el número la próxima vez, que es volver a ingresar el número en lugar de ingresar el resultado de la pantalla actual.
Luego, deje que el número se muestre actualmente como el número que se calcula para ingresar primero la pila de números. operation es el método de operación. Debido a que a un operador se ha hecho clic en esta vez, la próxima vez que haga clic en él, debe ignorar este operador y establecer ISOPT en falso.
El código de operación es el siguiente
// Compare la prioridad del operador de entrada actualmente y el operador de la pila del operador // Si la prioridad del operador superior es pequeña, el operador actual se coloca en la pila y no la calcula. // de lo contrario, el operador superior se coloca en la pila, y la pila de números se coloca en la pila para dos elementos en sucesión, y calcule // luego el operador actual se coloca en la pila. $ Scope.operation = function (actual) {// Si la pila de operadores está vacía, coloque directamente el operador actual en la pila if (! $ scope.opt.length) {$ scope.opt.push (actual); devolver; } operador var, derecha, izquierda; var lastopt = $ scope.opt [$ scope.opt.length-1]; // Si la prioridad actual del operador es mayor que el último operador, solo la pila se ingresa si ($ scope.ispri (actual, dastopt)) {$ scope.opt.push (actual); } else {operator = $ scope.opt.pop (); right = $ scope.num.pop (); izquierda = $ scope.num.pop (); $ scope.calculate (izquierda, operador, derecha); $ scope.operation (actual); }};Este método acepta el operador de entrada actualmente como parámetro. La idea central es que actualmente se recibe un operador. Si la pila del operador está vacía, el operador actual se colocará en la pila, y luego no hay necesidad de hacer nada más en este caso. Si la pila de operador actual no está vacía, entonces se aparece el elemento superior de la pila de operador actual, de modo que el operador recibido actualmente y el operador superior reciben prioridad (la prioridad de la multiplicación y la división es mayor que la adición y la resta, y el operador superior tiene prioridad de la misma prioridad porque se ingresa primero). El método ISPRI se utiliza para determinar la prioridad y recibir dos parámetros. El primero es el operador actualmente recibido y el segundo es el operador de primera línea en la pila. Si el operador actual tiene una prioridad más alta de acuerdo con las reglas mencionadas anteriormente, entonces el operador se colocará directamente en la pila. Si la prioridad del operador actual es menor que la parte superior del operador de pila, entonces debe realizar cálculos y cambiar la visualización de la calculadora. Los dos elementos en la parte superior de la pila del número de operación aparecen a su vez, ya que los dos números de operación para una operación, y luego la parte superior de la pila de la pila del operador se aparece como el operador para esta operación, y se llama el método de cálculo para el método de cálculo para la operación.
El código del método es el siguiente
// Responsable de calcular la función de resultado $ scope.calculate = function (izquierda, operador, derecha) {switch (operador) {case " +": $ scope.result = $ scope.format (número (izquierda) + número (derecho)); $ scope.num.push ($ scope.result); romper; caso " -": $ scope.result = $ scope.format (número (izquierda) - número (derecho)); $ scope.num.push ($ scope.result); romper; caso "×": $ scope.result = $ scope.format (número (izquierda) * número (derecho)); $ scope.num.push ($ scope.result); romper; caso "÷": if (right == 0) {$ scope.result = "error"; $ scope.init (); } else {$ scope.result = $ scope.format (número (izquierda) / número (derecho)); $ scope.num.push ($ scope.result); } romper; predeterminado: ruptura; }};Este método acepta tres parámetros, el número de operación izquierdo, el operador medio y el número de operación correcto, y cambia el resultado para mostrar el resultado después de sumar, restar, multiplicar y operar división, y coloca el resultado de cálculo en la pila del número de cálculo. Aquí es necesario tener en cuenta que si el cálculo es la división y el divisor es 0, se produce un error, los errores de visualización y todos los estados se borran, de lo contrario el cálculo es normal.
Después de completar una operación, los estados en la pila de operadores y la pila de números se cambiarán, y el valor actual de la clave actual no se ha puesto en la pila. Por lo tanto, el proceso anterior debe repetirse para la comparación de prioridad y luego se realiza la operación. De hecho, es un proceso recursivo hasta que la pila del operador esté vacía o la prioridad del operador actual es más alta que la parte superior del operador de la pila de operadores. El método ISPRI se utiliza para determinar la prioridad del operador.
El código es el siguiente:
// juzga si el operador actual tiene una prioridad más alta que la última, si se devuelve verdadero // de lo contrario, devuelve falso $ scope.ispri = function (actual, último) {if (current == last) {return false; } else {if (current == "×" || current == "÷") {if (last == "×" || last == "÷") {return false; } else {return true; }} else {return false; }}};Las reglas del juicio se han descrito anteriormente.
Además, existe un método checkOperator , que es determinar si el símbolo de entrada son los cuatro símbolos de operador de suma, resta, multiplicación y división.
El código es el siguiente:
// juzga si el símbolo actual es un símbolo operable $ scope.checkoperator = function (opt) {if (opt == "+" || opt == "-" || opt == "×" || opt == "÷") {return true; } return false; }Si es así, devuelva verdadero, de lo contrario, regrese falso.
Hasta ahora, todavía hay una rama con entrada igual al número que no
El código es el siguiente (conectado al método showResult)
// Si el clic es el signo igual si (a == "=" && $ scope.result! = "" && $ scope.result! = "Error") {$ scope.flag = false; $ scope.num.push ($ scope.result); while ($ scope.opt.length! = 0) {var operator = $ scope.opt.pop (); var right = $ scope.num.pop (); var izquierda = $ scope.num.pop (); $ scope.calculate (izquierda, operador, derecha); }}};Si la entrada es un signo igual, primero configure el indicador en False, lo que permite que la interfaz se reduzca la próxima vez que ingrese el número, y el número que se muestra actualmente debe colocarse en la pila como un número de cálculo. Luego debe realizar operaciones de apilamiento continuo hasta que la pila de operadores esté vacía antes de que pueda detenerse.
Resumir
Lo anterior es el código principal y el proceso de la implementación. Dado que hay muchos códigos de ramas, todas las ramas se dan a la vez y no se pueden describir en detalle. Por lo tanto, el método ShowResult está separado, que puede no ser adaptable. Dado que la escritura era Rush y no tomó demasiado tiempo para probar, puede haber algunos errores, por favor, indéngalos. Al mismo tiempo, debido a niveles limitados, este método puede no ser el mejor. Bienvenido a dar un mejor plan para comunicarse y aprender juntos ~~ Lo anterior es todo el contenido de este artículo. Espero que brinde ayuda al estudio o trabajo de todos.