مقدمة
بادئ ذي بدء ، دعونا لا نتحدث عن إنشاء المشروع الأساسي لـ AngularJS. من الأفضل استخدام أداة السقالات Yeoman لإنشائها مباشرة. إذا لم تكن هناك بيئة من هذا القبيل ، بالطبع ، يمكنك أيضًا تقديم المشروع عن طريق تنزيل ملف AngularJS بنفسك.
مثال مفصل التفسير
Main.js هو ملف JS الرئيسي للمشروع. جميع JS مكتوبة في هذا الملف. بعد التهيئة ، يكون رمز JS للملف كما يلي
الزاوي. module ('calculatorapp' ، ['nganimate' ، 'ngcookies' ، 'ngresource' ، 'ngroute' ، 'ngsanitize' ، 'ngtouch'] "1": ["AC" ، "+/-" ، "٪" ، "÷"] ، "2": ["7" ، "8" ، "9" ، "×"] ، "3": ["4" ، "5" ، "6" ، "-" ، "،" ، "،" ، "،" ، "،" "،" ، "،" ، "،" ، "،" "،" "،" "،" ، "،" "،" "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "يتم استخدام النتيجة هنا لربط نتائج الحساب بربط ثنائي الاتجاه ، والبيانات هي الأرقام والرموز الموجودة على لوحة مفاتيح الحاسبة.
جميع رموز CSS المتعلقة بهذا المشروع هي كما يلي:
*{الهامش: 0 ؛ Padding: 0 ؛} الجسم {padding-top: 20px ؛ حشو بوتوم: 20px ؛} H1 {text-align: Center ؛ اللون:#3385ff ؛}. Main {Margin: 20px Auto ؛ الحدود: 1 بكسل Solid #202020 ؛ القاع الحدودي: لا شيء ؛ العرض: 60 ٪ ؛ الارتفاع: 600px ؛}. النتيجة {display: block ؛ العرض: 100 ٪ ؛ الارتفاع: 30 ٪ ؛ الخلفية:#202020 ؛ حجم الصناديق: صندوق الحدود ؛ الحدود: لا شيء ؛ الحشو: 0 ؛ الهامش: 0 ؛ تغيير الحجم: لا شيء ؛ اللون: #fff ؛ حجم الخط: 80 بكسل ؛ محاذاة النص: صحيح ؛ ارتفاع الخط: 270 بكسل ؛ الفائض: مخفي. خلفية clip: border-box ؛}. الصف {الارتفاع: 14 ٪ ؛ الخلفية: #d7d8da ؛ حجم الصناديق: صندوق الحدود ؛ Border-Bottom: 1px Solid #202020 ؛ الفائض: مخفي ؛}. العقيد {الارتفاع: 100 ٪ ؛ حجم الصناديق: صندوق الحدود ؛ اليمين الحدودي: 1 بكسل Solid #202020 ؛ تعويم: اليسار. اللون: #202020 ؛ حجم الخط: 28 بكسل ؛ محاذاة النص: المركز ؛ Line-Height: 83px ؛}. العادي {العرض: 25 ٪ ؛}. end-no {width: 25 ٪ ؛ اليمين الحدودي: لا شيء ؛ الخلفية: #f78e11 ؛ اللون: #fff ؛}. Zero {Width: 50 ٪ ؛}. History {background: #3385ff ؛ اللون: #fff ؛ حجم الخط: 22px ؛ محاذاة النص: المركز ؛}ثم تخطيط HTML كما يلي:
<body ng-app = "cabulatorapp"> <h1> calculator for iOS8 </h1> <hr/> <p> {{history.join ("")}} </p> <viv> <textarea ng-model = "result"> ng-class = "showclass ($ index ، a)" ng-click = "showresult (a)"> {{a}} </div> </viv> </viv> </body> هنا ، يتم استخدام علامة P في سجل الفصل لعرض سجل الإدخال ، مما يعني أنه سيتم عرض جميع المفاتيح التي تضغط عليها لسهولة عرض النتائج. التاريخ هو صفيف أسفل النطاق الحالي ، والذي سيتم شرحه لاحقًا. هنا يتم استخدام textarea كشاشة العرض لنتائج الحساب ، وذلك أساسا لاستخدام ميزة الربط ثنائي الاتجاه. في الوقت نفسه ، يتم إنشاء كل عنصر مفتاح وعنصر واجهة في الآلة الحاسبة عن طريق الحلق على كائن البيانات. طريقة showClass هي طريقة أقل من النطاق ، والتي يتم استخدامها للحصول على سمات الفصل لعناصر عرض الواجهة غير المنتظمة. سيتم شرحه لاحقًا. طريقة showResult هي الطريقة الرئيسية للاستجابة للمفتاح. يتم الحصول على جميع ردودنا على المفاتيح من خلال هذه الطريقة ، وسنشرح بالتفصيل لاحقًا.
رمز طريقة showclass كما يلي:
// إظهار نمط الحاسبة $ scope.showclass = function (index ، a) {if (a == 0) {return "Zero" ؛ } فهرس الإرجاع == 3 || a == "="؟ "end-no": "Normal" ؛ } ؛تتعامل هذه الطريقة بشكل أساسي مع العمود الأخير من كل صف ليتم عرضه كبرتقالي ، ويجب أن تشغل المفاتيح التي تعرض 0 خلية للمعالجة الخاصة.
حتى الآن ، تم تنفيذ واجهة الآلة الحاسبة بالكامل
العروض كما يلي:
ما يلي يحتاج إلى تحقيق الاستجابة للمفاتيح. تتضمن المفاتيح مفاتيح Numeric ومفاتيح المشغل ومفاتيح AC. سيكون لكل مطبعة ردود مختلفة وهناك اتصال بين المفاتيح.
من أجل تسهيل شرح الكود ، يتم استخدام طريقة لإعطاء رمز طريقة العرض في الأجزاء ثم شرحه بالتفصيل.
بادئ ذي بدء ، نحتاج إلى إضافة عدة متغيرات للتحكم والتخزين.
// كومة الأرقام المستخدمة للحساب $ scope.num = [] ؛ $ scope.history = [] ؛ // stack stack $ scope.opt = [] ؛ // نتيجة الحساب للآلة الحاسبة $ scope.result = "" ؛ // نتيجة الآلة الحاسبة $ scope.result = "" ؛ //هذا يعني ما إذا كان سيبدأ العرض مرة أخرى. صحيح يعني عدم العرض مرة أخرى. وسائل كاذبة لمسح الإخراج الحالي وإعادة تشغيل الرقم $ scope.flag = true ؛ //هذا يعني ما إذا كان يمكن إدخال المشغل الآن. إذا كان يمكن أن يكون صحيحًا ، وإلا فإنه يكون scope $ false.isopt = true ؛
صفيف NUM هو في الواقع مكدس ، يستخدم لتلقي الأرقام التي أدخلها المستخدم. سيتم شرح الاستخدام المحدد لاحقًا. صفيف التاريخ هو كل المفاتيح التي أدخلها المستخدم. في كل مرة تضغط عليها ، يتم وضع الرموز أو الأرقام الموجودة على المفتاح في المكدس ، ثم يتم عرضها على الواجهة في الوقت الفعلي باستخدام الربط. صفيف OPT عبارة عن مكدس آخر يستخدم لتلقي إدخال المشغل من قبل المستخدم. سيتم شرح الاستخدام المحدد لاحقًا. العلم هو العلم. عندما يكون هذا صحيحًا ، فهذا يعني أن الرقم الذي تم الضغط عليه أثناء الضغط على الرقم هو جزء من الرقم المعروض حاليًا ويجب عرضه خلفه. على سبيل المثال ، يتم عرض الواجهة الحالية 12 ، ثم يتم الحكم على الضغط 3. إذا كان ذلك صحيحًا ، فسيتم عرض 123. خلاف ذلك ، سيتم مسح الواجهة و 3.isopt هو علم آخر. يتم منع المستخدم من المدخلات غير القانونية للمشغلين أثناء عملية الإدخال بشكل أساسي أثناء عملية الإدخال. على سبيل المثال ، يدخل المستخدم 1+ 2+ على التوالي. عند إدخال الإدخال هنا ، يجب أن يكون الإدخال أدناه رقمًا ، لكن المستخدم يدخل المشغل. من خلال الحكم على هذا العلم ، ستتجاهل الآلة الحاسبة هذا المشغل غير القانوني والحفاظ على الإدخال لا يزال 1+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 = // d/ig ، regdot = //./ig ، regabs = /// ig ؛ // إذا النقر فوق رقم إذا (reg.test (a)) {// القضاء على التجميد إذا ($ scope.isopt == false) {$ scope.isopt = true ؛ } if ($ scope.result! = 0 && $ scope.flag && $ scope.result! = "error") {$ scope.result += a ؛ } آخر {$ scope.result = a ؛ $ scope.flag = true ؛ }} يتم استخدام طريقة init لتهيئة بعض المتغيرات والأعلام لإعادتها إلى حالتها الأصلية. طريقة showResult هي الطريقة الرئيسية لعرض الواجهة للاستجابة لعمليات المستخدم. الرمز أعلاه هو فرع إذا كان هناك فرع في هذه الطريقة ، ويشير إلى أنه إذا تم إدخال إدخال المشغل ، فعندئذٍ إذا تم تجميد المدخلات إلى المشغل (لا يُسمح للمشغل حاليًا بإدخاله ، وسيتم تجاهله بعد الإدخال) ، فعند إدخال الرقم ، يتم إلغاء عدم إدخال مكدس المشغل في المرة القادمة. إذا لم تكن النتيجة المعروضة حاليًا فارغة وكان الرقم المضغوط جزءًا من الرقم المعروض حاليًا ولم يحدث أي خطأ ، فإن النتيجة المعروضة هي أن الرقم المضغوط حاليًا متصل بنهاية الرقم المعروض حاليًا. خلاف ذلك ، فهذا يعني أن الرقم الذي تدخله في المرة القادمة يحتاج إلى عرض بعد هذا الرقم عند إعادة اللعب.
رمز JS (تابع)
// إذا قمت بالنقر فوق ac else (a == "ac") {$ scope.result = 0 ؛ $ scope.init () ؛ }إذا تم النقر على AC ، فهذا يعني التهيئة ، ودع نتيجة العرض تكون 0 ، وتم مسح جميع الحالات.
رمز JS (تابع)
// إذا قمت بالنقر فوق نقطة عشرية أخرى إذا (a == ". }}
إذا كانت النقر فوق نقطة عشرية ، فليتم توصيل النقطة العشرية بنهاية الشاشة الحالية إذا لم تكن الشاشة الحالية فارغة ولم تكن هناك نقطة عشرية في نتيجة العرض الحالية.
رمز JS (تابع)
// إذا قمت بالنقر فوق مشغل عكسي آخر إذا (regabs.test (a)) {if ($ scope.result> 0) {$ scope.result = "-"+$ scope.result ؛ } آخر {$ scope.result = math.abs ($ scope.result) ؛ }}إذا كانت النقر عملية عكسية ، فستكون نتيجة العرض الحالية عكسيا
رمز JS (تابع)
// إذا قمت بالنقر فوق علامة مئوية أخرى إذا (a == "٪") {$ scope.result = $ scope.format (number ($ scope.result)/100) ؛ } إذا قمت بالنقر فوق علامة النسبة المئوية ، فقم بتقسيم النتيجة المعروضة الحالية على 100 ثم عرضها. هنا وظيفة format
الرمز كما يلي:
// format resump output $ scope.format = function (num) {var regnum =/. {10 ،}/ig ؛ if (regnum.test (num)) {if (//./. test (num)) {return num.toexponential (3) ؛ } آخر {return num.toexponential () ؛ }} آخر {return num ؛ }}} آخر {return num ؛ }}وظيفتها الرئيسية هي أن الآلة الحاسبة التي تأتي مع iOS8 لن تعرض العديد من الأرقام بلا حدود. إذا تجاوز 10 أرقام (بما في ذلك النقاط العشرية) ، فسيتم استخدام الحسابات العلمية لعرضها. من أجل البساطة ، عند استخدام الحسابات العلمية لنتائج العرض التي تحتوي على نقاط عشرية وتجاوز 10 أرقام ، دعها تحتفظ بعرض 3 أرقام بعد النقطة العشرية.
رمز JS (جزء showresult متصل)
// إذا لم تكن المشغل النقر ونتيجة العرض الحالية فارغة وخطأ آخر إذا ($ scope.checkoPerator (a) && $ scope.result! = "" && $ scope.result! = "error" $ scope.num.push ($ scope.result) ؛ $ scope.operation (a) ؛ // بعد النقر على المشغل مرة واحدة ، تحتاج إلى تجاهل الموقف الذي يتم فيه النقر على المشغل مرة أخرى. $ scope.isopt = false ؛ }
هذا الفرع هو الفرع الأكثر تعقيدًا ، مما يعني أنه إذا كان الإدخال هو عامل ، فسيتم تنفيذ العملية. لدخول هذا الفرع ، تحتاج إلى تعيين علامة على FALSE أولاً ، وهو إدخال الرقم في المرة القادمة ، وهو إعادة إدخال الرقم بدلاً من إدخال نتيجة العرض الحالية.
بعد ذلك ، دع الرقم المعروض حاليًا هو الرقم الذي يتم حسابه لإدخال مكدس الأرقام أولاً. طريقة operation هي طريقة التشغيل. نظرًا لأنه تم النقر على المشغل هذه المرة ، في المرة التالية التي تنقر عليها ، يجب عليك تجاهل هذا المشغل وتعيين ISOPT على FALSE.
رمز التشغيل كما يلي
// قارن أولوية مشغل الإدخال حاليًا ومشغل مكدس المشغل // إذا كانت أولوية المشغل العلوي صغيرًا ، فسيتم وضع المشغل الحالي على المكدس ولا يحسبه. // خلاف ذلك ، يتم وضع المشغل العلوي على المكدس ، ويتم وضع مكدس الرقم على المكدس لعنضتين على التوالي ، ويتم حساب // ثم يتم وضع المشغل الحالي على المكدس. $ scope.operation = function (current) {// إذا كانت مكدس المشغل فارغًا ، فضع المشغل الحالي مباشرة على المكدس if (! $ scope.length) {$ scope.opt.push (current) ؛ يعود؛ } VAR Operator ، اليمين ، اليسار ؛ var lastopt = $ scope.opt [$ scope.opt.length-1] ؛ // إذا كانت أولوية المشغل الحالية أكبر من المشغل الأخير ، فسيتم إدخال المكدس فقط إذا ($ scope.ispri (current ، lastOpt)) {$ scope.opt.push (current) ؛ } else {properator = $ scope.opt.pop () ؛ اليمين = $ scope.num.pop () ؛ اليسار = $ scope.num.pop () ؛ $ scope.calculate (يسار ، مشغل ، يمين) ؛ $ scope.operation (الحالي) ؛ }} ؛تقبل هذه الطريقة مشغل الإدخال حاليًا كمعلمة. الفكرة الأساسية هي أن المشغل يتم استلامه حاليًا. إذا كانت مكدس المشغل فارغًا ، فسيتم وضع المشغل الحالي على المكدس ، ثم لا توجد حاجة لفعل أي شيء آخر في هذه الحالة. إذا لم يكن مكدس المشغل الحالي فارغًا ، فسيتم إعطاء العنصر العلوي من مكدس المشغل الحالي ، بحيث يتم إعطاء أولوية المشغل المستقبل حاليًا والمشغل الأعلى (أولوية الضرب والتقسيم أكبر من الإضافة والطرح ، ويتم إعطاء المشغل الأعلى الأولوية لنفس الأولوية لأنه يتم إدخاله لأول مرة). يتم استخدام طريقة ISPRI لتحديد الأولوية واستلام معلمتين. الأول هو المشغل الذي تم استلامه حاليًا والثاني هو المشغل الأعلى على المكدس. إذا كان للمشغل الحالي أولوية أعلى وفقًا للقواعد المذكورة أعلاه ، فسيتم وضع المشغل مباشرة على المكدس. إذا كانت أولوية المشغل الحالي أصغر من الجزء العلوي من مشغل المكدس ، فأنت بحاجة إلى إجراء الحسابات وتغيير عرض الآلة الحاسبة. يتم عرض العنصرين الموجودين في الجزء العلوي من مجموعة رقم العملية بدوره ، حيث يتم عرض أرقام التشغيل اثنين لعملية واحدة ، ثم يتم عرض الجزء العلوي من كومة المشغل كمشغل لهذه العملية ، ويتم استدعاء طريقة الحساب لطريقة الحساب للتشغيل.
رمز الطريقة كما يلي
// مسؤولة عن حساب وظيفة النتيجة $ scope.calculate = function (يسار ، مشغل ، يمين) {switch (عامل التشغيل) {case " +": $ scope.result = $ scope.format (number (يسار) + رقم (يمين)) ؛ $ scope.num.push ($ scope.result) ؛ استراحة؛ حالة " -": $ scope.result = $ scope.format (الرقم (يسار) - الرقم (يمين)) ؛ $ scope.num.push ($ scope.result) ؛ استراحة؛ الحالة "×": $ scope.result = $ scope.format (الرقم (يسار) * رقم (يمين)) ؛ $ scope.num.push ($ scope.result) ؛ استراحة؛ الحالة "÷": if (right == 0) {$ scope.result = "error" ؛ $ scope.init () ؛ } آخر {$ scope.result = $ scope.format (الرقم (يسار) / الرقم (يمين)) ؛ $ scope.num.push ($ scope.result) ؛ } استراحة؛ الافتراضي: استراحة ؛ }} ؛تقبل هذه الطريقة ثلاث معلمات ، ورقم التشغيل الأيسر ، والمشغل الأوسط ورقم التشغيل الصحيح ، ويغير النتيجة لعرض النتيجة بعد إضافة وطرح وضرب وتشغيل التقسيم ، ويضع نتيجة الحساب في كومة رقم الحساب. من الضروري هنا أن نلاحظ أنه إذا كان الحساب هو الانقسام وأن المقسوم هو 0 ، يحدث خطأ ، وأخطاء العرض ، ويتم مسح جميع الحالات ، وإلا فإن الحساب طبيعي.
بعد اكتمال عملية واحدة ، سيتم تغيير الحالات الموجودة في مكدس المشغل وسيتم تغيير مكدس الأرقام ، ولم يتم وضع القيمة الحالية للمفتاح الحالي في المكدس. لذلك ، يجب تكرار العملية أعلاه لمقارنة الأولوية ثم يتم تنفيذ العملية. في الواقع ، إنها عملية متكررة حتى تصبح مكدس المشغل فارغًا أو أن تكون أولوية المشغل الحالي أعلى من قمة المشغل في مكدس المشغل. يتم استخدام طريقة ISPRI لتحديد أولوية المشغل.
الرمز كما يلي:
// الحكم على ما إذا كان المشغل الحالي له أولوية أعلى من الماضي ، إذا تم إرجاعه صحيح // وإلا ، فالتراجع عن scope.ispri = function (الحالي ، الأخير) {if (current == last) {return false ؛ } آخر {if (current == "×" || current == "÷") {if (last == "×" || last == "÷") {return false ؛ } آخر {return true ؛ }} آخر {return false ؛ }}} ؛تم وصف قواعد الحكم في وقت سابق.
بالإضافة إلى ذلك ، هناك طريقة checkOperator ، والتي تتمثل في تحديد ما إذا كان رمز الإدخال هو رموز المشغل الأربعة للإضافة والطرح والضرب والقسمة.
الرمز كما يلي:
// الحكم على ما إذا كان الرمز الحالي هو رمز قابلة للتشغيل $ scope.CheckOperator = function (OPT) {if (opt == "+" || opt == "-" || opt == "×" || opt == "÷") {return true ؛ } إرجاع خطأ ؛ }إذا كان الأمر كذلك ، فأعود صحيحًا ، وإلا عد كاذبة.
حتى الآن ، لا يزال هناك فرع له إدخال يساوي العدد الذي لم يكن كذلك
الرمز كما يلي (متصل بطريقة ShowResult)
// إذا كانت النقر هي علامة متساوية أخرى إذا (a == "=" && $ scope.result! = "" && $ scope.result! = "error") {$ scope.flag = false ؛ $ scope.num.push ($ scope.result) ؛ بينما ($ scope.opt.length! = 0) {var operator = $ scope.opt.pop () ؛ var right = $ scope.num.pop () ؛ var left = $ scope.num.pop () ؛ $ scope.calculate (يسار ، مشغل ، يمين) ؛ }}} ؛إذا كانت الإدخال علامة متساوية ، فقم بتعيين العلامة أولاً على خطأ ، مما يسمح للواجهة بإعادة تشغيل في المرة التالية التي تقوم فيها بإدخال الرقم ، ويجب وضع الرقم المعروض حاليًا في المكدس كرقم حساب. ثم تحتاج إلى إجراء عمليات تكديس مستمرة حتى تصبح مكدس المشغل فارغًا قبل أن تتوقف.
لخص
ما سبق هو الرمز الرئيسي وعملية التنفيذ. نظرًا لوجود العديد من رموز الفروع ، يتم تقديم جميع الفروع مرة واحدة ولا يمكن وصفها بالتفصيل. لذلك ، يتم فصل طريقة العرض ، والتي قد لا تكون قابلة للتكيف. نظرًا لأن الكتابة كانت Rush ولم تستغرق الكثير من الوقت للاختبار ، فقد يكون هناك بعض الأخطاء ، يرجى الإشارة إليها. في الوقت نفسه ، بسبب مستويات محدودة ، قد لا تكون هذه الطريقة هي الأفضل. مرحبًا بك لإعطاء خطة أفضل للتواصل والتعلم معًا ~~ ما سبق هو المحتوى الكامل لهذه المقالة. آمل أن يجلب بعض المساعدة لدراسة أو عمل الجميع.