קודקודייל
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
קודקודייל
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
ראשי ♦ אנגולר ♦ יסודות האנגולר- angular lifecycle and change detection

יסודות האנגולר- angular lifecycle and change detection

וינר יאיר 11 ביוני 2022 אין תגובות

הכל מתחיל בפקודת ng s . הקסם מתרחש , המנוע של אנגולר מתחיל לעבוד ופתאום יש לנו אפליקציה עם שלום עולם. יופי, כמה פשוט, אפשר להתחיל לייצר קומפוננטות ולעשות בלגן. אבל בשביל שלא נעשה בלגן יש כמה דברים שכדאי להכיר, על מנת לעבוד יעיל יותר, כך שנקבל בסופו של דבר מוצר טוב יותר שקל יותר לתחזק. נתחיל בהבנה ממש בסיסית של הדברים רק בשביל לגשת לנושא המרכזי של מדריך זה שהוא היכרות וחשיבות angular lifecycle.

אז בגדול, הקומפיילר של אנגולר רץ, עושה המון דברים שהם פחות רלוונטיים אלינו (כרגע) ואז מגיע השלב המעניין, הקובץ הראשון של אנגולר בשלב הראנטיים, פוגש את ngmodule , בשלב זה אנגולר אוסף את כל המודולים אימפורטס דקלריישנס הפרוביידרים ואז לבוטסטרפ ושם אנגולר מתחיל להסתכל על הקומפונטטנה שממנה מתחיל להיבנות עץ הקומפוננטות שלנו. 

יש לנו עץ קומפוננטות שנבנה על בסיס ההיררכיות, האפליקציה עובדת איזה יופי, מה עכשיו?

עכשיו יש דטה שמוזרם דרך עץ הקומפוננטות, הדטה עובר גם שינויים בדרך, מה זה אומר בעצם , רינדורים..

אנגולר רנדרינג על קצה המזלג

בלי להיכנס לעמוק של דברים, 

נתחיל ישר עם changedetection

שבודק את השינויים שהתרחשו בקומפוננה כלשהיא ומחלחל כלפי מטה.

כברירת מחדל, כל קומפוננטה תגיב לכל שינוי ותרנדר את התצוגה

Changedetectionstrategy.default

מה שאומר שאנגולר יהיה רגיש לכל שינוי שיתבצע במידע שמחזיקה הקומפוננטה וירנדר אותה ואת כל הקומפוננטות הקשורות לה. מה שעלול לגרום לbad performance. לצורך בדיקה והבנה תוך כדאי עבודה הכנתי אפליקציה פשוטה מאד עם המון בעיות , שניתן לסדר עם הבנה בסיסית של change detection וכן יש חשיבות להבנה של lifecycle hooks של אנגולר שגם כן נכסה את החומר הזה באותה נשימה.

אז שניה לפני הפרקטיקה, בואו נעיף מבט על משהו שאנחנו מכירים ונזכר ברצף הפעולות של lifecycle hooks

angular lifecycle

פרויקט אנגולר angular lifecycle and change detection

הורידו את הפרויקט מגיטהאב , שימו לב שיש ברנץ אחד של התיקון (master) ואחד של השגוי (incorrect):
Codcodile angular lifecycle and change detection – github

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

מה צריך לעשות

משימה ראשונה:

שימו לב שיש שגיאה בקונסול – ExpressionChangedAfterItHasBeenCheckedError Explained. נובעת מהסיבה שבוצע שינוי בVIEW לאחר שאנגולר בדק אם היו שינויים כל שהם ברכיב (changedetection). ולכן אנגלור זורק את השגיאה כי השינוי לא קרה בסדר של הלייפסייקל , כפי שאפשר לראות השגיאה לא שובר את האתר באמת. אבל מבחינת אנגולר, מצב זה תקין.
ברוב המקרים זה קורה כי השתמשנו בlifecycle hook לא מתאים שמבצע עדכון של הקומפוננטה. אך במקרה שלנו אנחנו רוצים להשאיר את העדכון בngAfterViewInit או ngAfterViewChecked ולנסות לסדר את הבעיה עם ChangeDetectionStrategy . כך למעשה אנגולר השליטה בChangeDetection תהיה בידיים שלנו.

משימה שניה:

למנוע מריצות מיותרות של פונקציות. שימו לב שכל שינוי קטן באפליקציה, למשל הקלדה בINPUT מבצעת הדפסות לקונסול (check renders) בפונקציות שנמצאות בכלל ברכיבים לא קשורים לINPUT מה שמעיד על רנדורים מיותרים שעולים לנו בביצועים.

משימה שלישית:

שימו לב שלחוצים על הצאקבוקס להוסיף לdone זה לא עובד. יש כאן בעיה שצריך לבדוק במקרה זה כי ChangeDetectionStrategy לא עובד לטובתנו. כי הוא לא רגיש לשינוים במקרה הזה נוכל להגיד ל לאנגולר כי יש שינוי ואנחנו מעוניינים שהתייחס אליו . אז זה נעשה עם ChangeDetectorRef detectChanges.

הערה חשובה:

שימוש לב לPIPE שלנו, הוא מוגדר על pure:false . זה גם נושא שיש להיזהר ממנו, כי עלול גם לזלול לכם משאבים מיותרים. עם ChangeDetectionStrategy.OnPush לרוב לא תהיה לכם בעיה איתו.

חשוב לציין! התרגיל הוא לא best practice

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

להלן כמה קבצי דוגמה של האפליקציה השגויה

import { AfterViewChecked, ChangeDetectionStrategy, ChangeDetectorRef, Component, DoCheck, OnChanges, OnDestroy, OnInit } from '@angular/core';
import { HandleListService } from './handle-list.service';


export enum StatusTodo {
  NEW,
  DONE
}
export interface ITodos {
  text: string;
  id: number;
  status: StatusTodo
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  // changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent implements OnInit, DoCheck, AfterViewChecked, OnDestroy {
  
  public todos: ITodos[];
  public counter: number = 0;
  public timer : ReturnType<typeof setTimeout> = null;
  public time : string = new Date().toLocaleTimeString();

  constructor(private todosService : HandleListService, private cdr:ChangeDetectorRef){};
 
  ngDoCheck() {
   if(this.counter < this.todos.length) {
      this.todos = this.todosService.todos;
    }
  };

  ngOnInit(){
    this.todos = this.todosService.todos; 
    
    this.timer = setInterval(()=> {
      this.time = new Date().toLocaleTimeString();
      this.cdr.detectChanges();
    }, 1000);
  }
  ngAfterViewChecked(): void{
    this.counter = this.todos.length;
  }

  
  ngOnDestroy(){
    clearInterval(this.timer);
  }

}
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DoCheck, Input, OnInit } from '@angular/core';
import { ITodos, StatusTodo } from 'src/app/app.component';
import { HandleListService } from 'src/app/handle-list.service';

@Component({
  selector: 'app-todo-list',
  templateUrl: './todo-list.component.html',
  styleUrls: ['./todo-list.component.scss'],
  // changeDetection: ChangeDetectionStrategy.OnPush
})
export class TodoListComponent implements OnInit, DoCheck {

  @Input() todos: ITodos[];
  @Input() counter : number = 0;
  public statusNew : StatusTodo = StatusTodo.NEW;
  public indexChecked : number = 0;

  constructor(private todosService : HandleListService, private cdr: ChangeDetectorRef) { }

  ngDoCheck(): void {
  }


  ngOnInit(): void {

  }

  checkDetec() {
    console.log('check renders')
    console.log(this.counter)
  }


  moveToDone(index: number): void{
    this.todosService.changeStatus(index , StatusTodo.DONE);
    // this.cdr.detectChanges();
  }

}
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { ITodos, StatusTodo } from 'src/app/app.component';
import { HandleListService } from 'src/app/handle-list.service';

@Component({
  selector: 'app-add-todo',
  templateUrl: './add-todo.component.html',
  styleUrls: ['./add-todo.component.scss'],
  changeDetection: ChangeDetectionStrategy.Default
})
export class AddTodoComponent implements OnInit {

  public newToDo : string = null;
  constructor(private todosService : HandleListService, private cdr: ChangeDetectorRef) { }

  ngOnInit(): void {
  }

  public addTodo() : void {
    const newTodo : ITodos = {text: this.newToDo , id: Math.random()*1356, status: StatusTodo.NEW};
    this.newToDo = null;
    this.todosService.addTodo(newTodo);
  }

}

איך בודקים ביצועים וchangedetection באנגולר

פוסטים קשורים:

אפשרויותAngular nested routes angular micro-frontendAngular Microfrontend Module Federation Tutorial – Part 2 אנגולר NavigationExtras – skipLocationChange chatChat – angular, nodejs and socket.io
angular אנגולר לימודי אנגולר מדריך אנגולר

אודות המחבר

יאיר וינר להציג את כל הפוסטים של וינר יאיר


« פוסט קודם
פוסט הבא »

השארת תגובה

ביטול

חיפוש באתר
בחירת העורכים
29 בדצמבר 2023 עידן יצחקי

שדה טקסט עשיר עם תמונות

אתם הולכים להיות מופתעים עד כמה HTML יכול להיות חכם ולבצע משהו כל כך מורכב, שאם אנחנו היינו רוצים ליצור

1 באוקטובר 2021 עידן יצחקי

איך למשוך דינמית favicon של אתרים אחרים ב-JS

בפוסט זה נראה איך אפשר על פי לינקים בדף למשוך את ה-favicon מהדומיין שלהם באופן דינמי, בדיקה של תקינות התמונה

פופולרי
Javascript functions – היכרות עם סוגי פונקציות
Javascript
21 בדצמבר 2024 אין תגובות
Nested routing in angular standalone component
Typescript
15 בנובמבר 2024 אין תגובות
בחרו לפי תגיות
angular blockchain css ethers express front-end fullstack GQL html javascript next js nextjs nodejs react hooks reactjs solidity webgl אנגולר בלוקציין וורדפרס לימודי אנגולר לימודי וורדפרס לימוד ריאקט מדריך front-end מדריך GQL מדריך אנגולר מדריך וורדפרס מדריך חינם react מדריך ריאקט מפתח בלוק מפתח בלוקציין מתכנת front-end מתכנת בלוקציין מתכנת פרונט סולידיטי קורס front end קורס fullstack קורס nextjs קורס אנגולר קורס בלוקציין קורס בלוקציין בחינם קורס סולידיטי קורס ריאקט קורס תכנות קורס תכנות בחינם
סינון על פי קטגוריות
CSS fullstack HTML IIS Javascript nodeJs SEO Typescript אנגולר בלוקציין בניית אתרים וורדפרס חיפוש עבודה כלים נוספים כללי נגישות קורסים ריאקט תלת מימד תקלות ופתרונות
צור קשר
כל הזכויות שמורות לקודקודייל
ליצירת קשר: @ קודקודייל
גלילה לראש העמוד
דילוג לתוכן
פתח סרגל נגישות כלי נגישות

כלי נגישות

  • הגדל טקסטהגדל טקסט
  • הקטן טקסטהקטן טקסט
  • גווני אפורגווני אפור
  • ניגודיות גבוההניגודיות גבוהה
  • ניגודיות הפוכהניגודיות הפוכה
  • רקע בהיררקע בהיר
  • הדגשת קישוריםהדגשת קישורים
  • פונט קריאפונט קריא
  • איפוס איפוס