در این آموزش که بخش دوم آموزش مقدماتی انگولار 8 است قصد داریم با هم، اولین پروژه FrontEnd خود با Angular 8 را ایجاد کنیم. در این بخش به بررسی قابلیت Data Binding در انگولار خواهیم پرداخت. لطفا با ما تا انتها همراه باشید.
کدهای این آموزش در آدرس زیر قابل مشاهده و دانلود است
https://github.com/MohammadMoeinFazeli/Angular8-FirstProjectCalculator
این پست بخش دوم آموزش ایجاد اولین پروژه با Angular 8 است. برای مطالعه ی بخش اول از لینک زیر استفاده کنید:
Data Binding به قابلیتی از Angular گفته می شود که امکان ارتباط بین ظاهر و منطق برنامه (یعنی بین قالب HTML و کدهای TypeScript) را به سادگی فراهم می کند. در انگولار انواع مختلفی از Data Binding وجود دارد که عبارتند از:
1- الحاق یا Interpolation: یک جریان یک طرفه از component به سمت DOM (یا همان HTML) ایجاد می کند. برای این کار باید یک متغییر در کلاس component تعریف و سپس برای استفاده از آن در قالب HTML از علامت {{نام متغییر}} استفاده کنید.
2- انقیاد ویژگی ها یا Property binding: از طریق این روش می توانید ویژگی های یک المان یا کامپوننت درون قالب HTML را با متغییرها مقداردهی کنید که به محض تغییر مقدار آن متغییر، آن المان مجددا رندر شده و تغییر یابد. برای اینکار می توانید از علامت براکت یا [] استفاده کنید. مثلا در کد زیر مقدار ویژگی value از المان input توسط متغییر foobar تعیین می شود:
<input type="text" [value]="foobar">
3- انقیاد رخداد یا Event binding: یک جریان داده ای از DOM به سمت component ایجاد می کند. یعنی در زمانی که یک رخداد DOM نظیر click روی یکی از المان ها اتفاق افتاد، تابع bind شده به آن اجرا خواهد شد. مثلا در کد زیر تابع ()sayHi به محض کلیک کردن button اجرا می شود:
<button (click)="sayHi()">Hi</button>
4- انقیاد دوطرفه یا Two-way data binding: یک جریان داده ای دو طرفه را ایجاد می کند. برای این کار باید از directive ویژه ای به نام ngModel استفاده کرد. برای مثال در کد زیر مقدار فیلد input توسط متغییر foobar تعیین می شود، همچنین اگر کاربر مقدار جدیدی در فیلد input وارد کند مقدار متغییر foobar نیز تغییر خواهد یافت:
<input type="text" [(ngModel)]="foobar">
خوب اکنون پس از یادگیری مفاهیم اولیه بهتر است به سراغ ادامه ی پیاده سازی ماشین حساب خود برویم. در یک ماشین حساب ما چهار دسته کلید زیر را داریم:
1- اعداد (از 1 تا 9)
2- عملگرها ( +, -, *, /, = )
3- اعشار (.)
4- کلید پاک کردن یا reset
برای پیاده سازی منطق برنامه، در ابتدا به سراغ فایل src/app/calculator/calculator.component.ts بروید و متغییرهای کلاس CalculatorComponent خود را به صورت زیر تعریف کنید:
export class CalculatorComponent implements OnInit {
currentNumber = '0';
firstOperand = null;
operator = null;
waitForSecondNumber = false;
متغییر currentNumber مقدار نشان داده شده در ماشین حساب را نگه می دارد. متغییر firstOperand مقدار عملوند اول را نگه می دارد. متغییر operator برای عملگر استفاده می شود و متغییر waitForSecondNumber یک مقدار دودویی را نگه می دارد که در صورت true بودن یعنی کاربر عملوند اول را وارد کرده است و سیستم منتظر وارد شدن عملوند دوم توسط کاربر است.
سپس تابع ()getNumber را که برای گرفتن مقدار عدد فعلی است مطابق کد زیر در کلاس CalculatorComponent قرار دهید:
public getNumber(v: string){
if(this.waitForSecondNumber)
{
this.currentNumber = v;
this.waitForSecondNumber = false;
}else{
this.currentNumber === '0'? this.currentNumber = v: this.currentNumber += v;
}
}
سپس تابع ()getDecimal که برای الحاق مقدار . به عدد فعلی است به صورت زیر ایجاد کنید:
getDecimal(){
if(!this.currentNumber.includes('.')){
this.currentNumber += '.';
}
}
حال به سراغ ایجاد تابع ()doCalculation که وظیفه ی انجام محاسبات براساس عملوند انتخابی را برعهده دارد بروید. برای این منظور از کد زیر استفاده کنید:
private doCalculation(op , secondOp){
switch (op){
case '+':
return this.firstOperand += secondOp;
case '-':
return this.firstOperand -= secondOp;
case '*':
return this.firstOperand *= secondOp;
case '/':
return this.firstOperand /= secondOp;
case '=':
return secondOp;
}
}
سپس تابع ()getOperation را که وظیفه ی اصلی مدیریت انجام محسابات را برعهده دارد به صورت زیر تعریف کنید:
public getOperation(op: string){
console.log(op);
if(this.firstOperand === null){
this.firstOperand = Number(this.currentNumber);
}else if(this.operator){
const result = this.doCalculation(this.operator , Number(this.currentNumber))
this.currentNumber = String(result);
this.firstOperand = result;
}
this.operator = op;
this.waitForSecondNumber = true;
console.log(this.firstOperand);
}
در نهایت تابع ()clear که برای پاک کردن ماشین حساب و برگرداندن متغییرها به حالت اولیه است به صورت زیر ایجاد کنید:
public clear(){
this.currentNumber = '0';
this.firstOperand = null;
this.operator = null;
this.waitForSecondNumber = false;
}
اکنون باید با استفاده از قابلیت data binding این توابع را به المان های DOM خود bind کنید.
Property binding در Angular
اکنون باید متغییر currentNumber را به ویژگی value در المان input ماشین حساب خود bind کنیم که به محض تغییر این متغییر، مقدار نمایش داده شده در input نیز تغییر یابد. برای این منظور کد زیر را در src/app/calculator/calculator.component.html تغییر دهید:
<div class="calculator">
<input type="text" class="calculator-screen" [value]="currentNumber" disabled />
<!-- [...] -->
Event Binding در Angular
در انقیاد یا Bind کردن توابع به رخداد کلیک المان های مربوطه از کد زیر استفاده کنید. با این کار پس از کلیک کردن روی هرکدام از دکمه های ماشین حساب، تابع bind شده به آن اجرا خواهد شد و عمل مورد نظر ما را انجام می دهد:
<div class="calculator">
<input type="text" class="calculator-screen" [value]="currentNumber" disabled />
<div class="calculator-keys">
<button type="button" (click) = "getOperation('+')" class="operator" value="+">+</button>
<button type="button" (click) = "getOperation('-')" class="operator" value="-">-</button>
<button type="button" (click) = "getOperation('*')" class="operator" value="*">×</button>
<button type="button" (click) = "getOperation('/')" class="operator" value="/">÷</button>
<button type="button" (click) = "getNumber('7')" value="7">7</button>
<button type="button" (click) = "getNumber('8')" value="8">8</button>
<button type="button" (click) = "getNumber('9')" value="9">9</button>
<button type="button" (click) = "getNumber('4')" value="4">4</button>
<button type="button" (click) = "getNumber('5')" value="5">5</button>
<button type="button" (click) = "getNumber('6')" value="6">6</button>
<button type="button" (click) = "getNumber('1')" value="1">1</button>
<button type="button" (click) = "getNumber('2')" value="2">2</button>
<button type="button" (click) = "getNumber('3')" value="3">3</button>
<button type="button" (click) = "getNumber('0')" value="0">0</button>
<button type="button" (click) = "getDecimal()" class="decimal" value=".">.</button>
<button type="button" (click) = "clear()" class="all-clear" value="all-clear">AC</button>
<button type="button" (click) = "getOperation('=')" class="equal-sign" value="=">=</button>
</div>
</div>
بسیار عالی. کار تمام است و پروژه ی شما آماده شده است. با دستور ng serve پروژه ی خود را اجرا کنید و خروجی کار را بررسی کنید.
امیدوارم این آموزش برای شما مفید باشد. مجددا یادآوری می کنم که کدهای این آموزش در آدرس https://github.com/MohammadMoeinFazeli/Angular8-FirstProjectCalculator قابل استفاده و دانلود است.
اگر سوالی داشتید لطفا در بخش دیدگاه های این پست، سوال خود را مطرح کنید.
موفق باشید. التماس دعا
سلام، خیلی ممنونم از آموزش کاملتون.
فقط یه سوال داشتم، کد مربوط به کلیدی که فقط یک عدد قبلی را پاک کند (نه کل عدد) مثل این علامت -> بر روی ماشین حساب در قسمت پیاده سازی منطق، میفرمایید.
سلام ممنونم… می تونید ابتدا عدد را به string تبدیل کنید و بعد با متد substring یا slice آخرین رقم را حذف کنید و مجددا string را به عدد تبدیل کنید
سلام وقتتون بخیر می خواستم بدونم این کد ها فقط برای انگولار 8 قابل اجراست؟ چون روی ورژن انگولار 10 از بیشتر موارد مثل this.firstOperand ارور میگیره و میگه مقداره اولیه ی this.firstOperand تو قسمت private doCalculation به صورت null هستش یا (op , secondOp) حتما باید یه تایپی داشته باشن مثل any یا … . می خواستم بدونم چطوری می تونم این ارور هارو برطرف کنم؟
سلام… برای ورودی ها و خروجی توابع type تعیین کنید… اگر تایپی مدنظرتون نیست از any استفاده کنید
Ready good