אנגולר Data-binding

‏ • 2 באוקטובר, 2020

מהי המשמעות של מושג זה?

הקשר בין ה-html לבין הנתונים והלוגיקה. קישור נתונים מתוך קבצי ts לתוך ה-html. לכל קטע של html ישנו קלאס בקובץts  המתאים לו. כל קטע html יכול להשתמש בשדות שמוגדרות בקלאס שלו, בקומפוננט שלו, ורק בהם. בהמשך, יפורטו עוד אפשרויות.

ישנם 4 סוגים עיקריים של קשר בין הלוגיקה/המידע לבין ה-html:

  1. String binding
  2. Property binding
  3. Event binding
  4. 2-ways-binding

1. String binding

קישור נתונים של string . הקישור יתבצע ע"י שימוש ב {{ }}. לדוגמא:

export class AppComponent  {
   name = 'Angular 8';
}

app.component.html

<div>{{name}}</div>

התוכן המשתנה name יופיע בתוך ה div.

חשוב לציין, לא רק ערכי string ממש יכולים להופיע בתוך הסוגריים הכפולים, אלא כל ערך שיכול ע"י המרה לקבל ערך של string. ניתן להכניס ערך מספרי, ואפילו פונקציה שמחזירה ערך, כיון שהערך המוחזר מקבל המרה ל-string. זה גם יכול להיות ערך בוליאני, וההמרה האוטומטית תהיה "true/false" לפי הערך. לדוגמא:

export class AppComponent  {
   isRight:boolean=true;
}

התוכן של <div>{{ isRight }}</div> יהיה תקין והפלט יהיה true.
מה לא יהיה תקין?
לא ניתן לרשום מספר פקודות, או התניה וכדומה.

חשוב! כאשר קוראים לקומפוננט, מיד נוצר מופע של הקלאס המתאים ואפשר כבר להשתמש עם הערכים של השדות. הקלאס המתאים הוא הקלאס של הקומפוננט (מפורט בשיעור 1).

שימוש בקומפוננט מספר פעמים:

לכל קומפוננט קיים מופע משל עצמו, ולכן אם משתמשים בקומפוננט מספר פעמים, ייווצרו מספר מופעים של אותו הקלאס. שינוי ערך של שדה בקומפוננט אחד אינו משפיע על שדה בקומפוננט אחר למרות שנראה שאם מדובר באותו קומפוננט כל השדות מקושרים. אין ביניהם כל קשר, שהרי מדובר במופעים שונים לחלוטין. לדוגמא – להלן קריאה לקומפוננט פעמיים:

<first-name>{{name}}</first-name>
<first-name>{{name}}</first-name>

יש כאן קריאה פעמיים לאותו קומפוננט, ולכן ייווצרו 2 מופעים מסוג FirstNameComponent.

אם ישתנה השדה name של אחד מהם, הערך name של הקומפוננט השני אינו משתנה בהתאם, היות ומדובר במופעים שונים.

2. Property binding

שינוי ערכי ה-properties של תגיות html יהיה ע"י סוגריים מרובעות.

לדוגמא, כפתור יהיה disabled בהתאם לערך המשתנה המקושר:

<button [disabled]="isRight">press</button>

מה ההבדל בין Property לבין attribute?

ה-dom הוא התוצאה של ה-html למשתמש. ישנו קטע קוד html שבו מוגדרות התגיות השונות. לזה קוראים html. לאחר "קימפול", הפעלה של קוד Js ועוד, הקובץ מתורגם ל-dom וזה מה שלמעשה מוצג למשתמש. לדוגמא אם יש מאפיין של display:none ה-dom יתרגם את המסך בצורה כזאת שהתגית הצריכה להיות מוסתרת אכן תהיה מוסתרת.

Attribute הוא מאפיין השייך ל-html. אם המסך אינו מתרנדר, גם אם משנים את ה-attribute של ה-html, המשתמש למעשה נשאר עם ה-dom הקודם ואינו רואה את השינוי. באנגולר זה יכול לקרות, מכיון שניתן לשנות ישירות ערכי attr מבלי לרנדר את הדף.

Property הוא מאפיין השייך ל-dom. אם משניםprop  ועדיין המסך לא התרנדר, השינוי יקבל תוקף באופן מיידי, היות והמשתמש תמיד רואה את תוצאת ה-dom.

ולכן באנגולר, יש לפנות תמיד ל-prop על מנת לקבל שינוי מיידי. השמות של ה-attr ושל ה-prop ברובם זהים. הבדל עיקרי באנגולר הוא, שכאשר יש צורך לשנות ערך של prop יש לפנות ע"י סוגריים מרובעות. ואילו ל-attr לא פונים עם סוגריים מרובעות.

פנייה ל attr  אינה מומלצת במצבים דינמיים.

3. Event binding

הפעלת קוד ע"י אירוע. הקוד יכול גם להיות קריאה לפונקציה. יש לעטוף את האירוע בסוגריים עגולים.

רוב האירועים המוכרים מ-javascript ייכתבו אותו הדבר באנגולר, מלבד הקידומת "on".

אירועים של: onclick ,onmousehover ייכתבו באנגולר (click) ,(mousehover) וכן הלאה.

בקובץ ה-ts הגדרת הפונקציה כאשר היא בתוך הקלאס נכתבת ללא המילה "function". כמו כן, פניה למשתנים בתוך פונקציה תהיה ע"י קידומת "this".

לדוגמא:

export class AppComponent  {
   isRight:boolean=false;
  enableBtn(){
  this.isRight=true;
}}

app.component.html

<button [disabled]="isRight" (click)="enableBtn();">press</button>

בלחיצה על הכפתור, הפונקציה המקושרת לאירוע מתבצעת ותפקידה לשנות את הערך של המשתנה isRight. המשתנה הזה מקושר ל-property של disabled ולכן ברגע שלוחצים על הכפתור, הכפתור מקבל disabled='true' שזה בעצם נעילת הכפתור…

אגב, אירוע click)) אינו מוכרח להיות מוגדר דווקא בתגית button אלא יכול להיות מוגדר גם על תגית של div ועוד תגיות רבות מקבלות אירוע זה.

4. 2-ways-binding

כיצד משנים ערך של שדה דרך input?

לכאורה היה צורך בשני שלבים:

שלב ראשון, לקשר את ה-input לאירוע של keyup וכל הוספת תו, האירוע יקרא לפונקציה שתעדכן את הערך של השדה לערך החדש שנוצר לאחר הוספת תו.

שלב שני, לקשר את ה-value של ה-input  לשדה.

לדוגמא:

<input [value]="myName" (keyup)="myFunc()"/>

במקום זה, ניתן להגדיר את הקישור בפקודה אחת.

הקישור יוגדר כך:

</ [(ngModel)]="myName"  <input

שימו לב! ngModel אות גדולה של ,M וזה לא ngMoudle

לדוגמא:

export class AppComponent  {
   isRight:boolean=false;
   myName='' ";
}

app.component.html

<input type="text" [(ngModel)]="myName"/>

יש להוסיף הצהרה של FormsModule בקובץ app.module.ts שנמצא

תחת תיקיית app.

import { FormsModule } from '@angular/forms';

וכן, יש להוסיף למערךimports  את FormsModule:

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
…
})

ניתן להוסיף ל-html תגית שבו ניתן יהיה לצפות מיד בשינוי ה-Input את השינוי.

לדוגמא:

<div>{{myName}}</div>

 

תגיות: ,

תגובות בפייסבוק