תחי ישראל - אין לנו ארץ אחרת

תחי ישראל -אין לנו ארץ אחרת

כיצד לשתף מידע באפליקציה אנגולרית באמצעות custom services?

מחבר:
בתאריך:

מדריך זה מסתמך על המדריך הקודם בסדרה, בו הסברנו כיצד לכתוב אפליקציה מבוססת דף יחיד באמצעות AngularJS.

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

הדרך הפשוטה ביותר שמאפשרת לנו לשתף קוד בין הקונטרולרים היא באמצעות השימוש ב-custom service.

כדי ליצור- custom service נשתמש בתחביר הבא:


myApp.service('serviceName', function(){
   // the code for the custom service, variables, functions
});

את ה-service אנחנו יוצרים על ידי שימוש בפונקציה האנגולרית service, על האפליקציה הקיימת (myApp בדוגמה).

ה-service מקבל שני פרמטרים:

  • שם ה-service
  • ופונקציה אנונימית שמכילה את הקוד שאנחנו רוצים שיהיה ב-service.

הקוד ב-service יכלול משתנים ופונקציות שאנחנו רוצים לשתף בין הקונטרולרים.

 

האפליקציה

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

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

האפליקציה הזו מדגימה העברת נתונים בין הדפים (ובין הקונטרולרים) באפליקציה אנגולרית מבוססת דף יחיד באמצעות custom service.

כנסו כנסו לגרסת הדגמה של האפליקציה בקישור להלן.

לאפליקציה

 

צעד 1: הגדרת האפליקציה

נכתוב את האפליקציה 'myApp', ונעביר את התלות ngRoute ( אם משהו לא מובן נא לקרוא את המדריך בנושא אפליקציה אנגולרית מבוססת דף יחיד ).


var myApp = angular.module('myApp', ['ngRoute']);

 

צעד 2: נגדיר את הנתיבים של האפליקציה

נשתמש בפונקציה האנגולרית config כדי להגדיר את הנתיבים של האפליקציה. הנתיבים הם first/ ו- second/, שמקשרים לטמפלייטים ולקונטרולרים שיטפלו בהם.


myApp.config(function($routeProvider) {

  $routeProvider.
  when('/first', {
     templateUrl: 'pages/first.html',
     controller : 'firstController'
  }).
  when('/second', {
     templateUrl: 'pages/second.html',
     controller : 'secondController'
  }).
   otherwise({
     redirectTo: '/first'
  });
});

 

צעד 3: הקונטרולרים

נוסיף את שני הקונטרולרים.

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

  • נעביר לו את ה-service שניצור בהמשך המדריך בתור פרמטר.
  • המשתנה num יכיל את הערך שבחר המשתמש.
  • המשתנה activityState יהפוך לאקטיבי רק בתנאי שהמשתמש בחר את אחד המספרים.
  • הפונקציה chooseNumber משנה את הערך של המשתנה num בהתאם לבחירת המשתמש, ובתגובה להקלקה של המשתמש על בחירתו.
  • הפונקציה init קוראת לעצמה, ומופעלת בכל פעם שנכנסים או חוזרים לקונטרולר, ומציבה את ערך המשתנים, בהתאם לערכים השמורים ב- service.
myApp.controller('firstController', function($scope, guessNumberService){
    $scope.num = null;
    $scope.activityState = false;
    
    ($scope.init = function(){
        $scope.num = guessNumberService.getUserSelectedNumber();
        $scope.activityState = guessNumberService.getActivityState();
    }());
    
    $scope.chooseNumber = function(int, e){
        e.preventDefault();

        $scope.activityState = true;
        $scope.num = int;

        guessNumberService.setActivityState(true);
        guessNumberService.setUserSelectedNumber(int);
    }
});

 

הקונטרולר השני אומר למשתמש האם המספר שבחר הוא המספר הנכון באמצעות הפונקציה isTheNumber מה- service.

myApp.controller('secondController', function($scope, guessNumberService){
    $scope.result = guessNumberService.isTheNumber();
});

 

צעד 4: ה-custom service

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

מה שזה אומר ברמת הקוד זה שצריך להעביר את המידע אודות בחירת המשתמש מהקונטרולר הראשון לשני. כדי לשתף קוד בין הקונטרולרים נשתמש ב-custom service.

נוסיף לקוד custom service ששמו guessNumberService.


myApp.service('guessNumberService', function(){
});

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

  • המשתנה number שמכיל את המספר, שאותו נגדיר מראש, ואותו המשתמש צריך לנחש.
  • המשתנה userSelectedNumber, שיעודכן במספר שהמשתמש ניחש.
  • הפונקציה setUserSelectedNumber שמקבלת את הערך שהמשתמש בחר. הפונקציה מציבה את הערך לתוך המשתנה userSelectedNumber, רק בתנאי שמדובר במספר תקין.
  • והפונקציה isTheNumber שבודקת האם, בפועל, המשתמש ניחש את המספר הנכון. היא משווה את הערך שבחר המשתמש לערך שהוגדר מראש, ומחזירה הודעה שניתן להציג למשתמש.

myApp.service('guessNumberService', function(){
    var thisController = this;

    this.number = 3;
    this.userSelectedNumber = null;
    this.activityState = false;
    
    this.setUserSelectedNumber = function( number ){
        var number = parseInt(number, 10);
    
        if(!isNaN(number))
            thisController.userSelectedNumber = number;
    };
    
    this.getUserSelectedNumber = function(){
        return this.userSelectedNumber;
    };

    this.isTheNumber = function(){
        return (thisController.number === this.userSelectedNumber)? 
	'זה המספר שחשבתי עליו!' 
	: 
	'זה לא המספר. נסה שנית!';
    };
	
    this.setActivityState = function(bool){
        this.activityState = bool;
    };
	
    this.getActivityState = function(){
        return this.activityState;
    };
});

שימו לב, לשימוש ב-this וב-thisController.

הפונקציה (isTheNumber) והמשתנה (number) מוגדרים עם מילת המפתח this, שמשייכת אותם לפונקציה שבתוכה הם נמצאים (שזה הקונטרולר).

בתוך הפונקציה (isTheNumber) אנחנו צריכים גישה ל-number שמוגדר בקונטרולר. אם ננסה לגשת אליו באמצעות this, נתקל בבעיה, מפני ש-this בתוך הפונקציה יצביע על הפונקציה, ולא על הקונטרולר.

כדי לפתור את הבעיה, יצרנו את המשתנה thisController, שמקבל את הערך של this שמצביע על הקונטרולר. ואז, בתוך הפונקציה, אנחנו משתמשים ב-thisController כדי להצביע על המשתנה number שמוגדר על הקונטרולר.

 

צעד 5: הטמפלייטים

הטמפלייט הראשי ב-index.html יכיל את הדיב שאת תוכנו נעדכן עם הטמפלייטים המשניים.


<div ng-view></div>

בנוסף, ישנם שני טמפלייטים משניים, כפי שהגדרנו בצעד השני.

pages/first.html

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

  • לחיצה על הקישור מעבירה לפונקציה chooseNumber את המספר הנבחר באמצעות ng-click.
  • הקישור מקבל קלאס active באמצעות ng-class.

<h1>בבקשה לנחש את המספר</h1>

<ul class="pagination">
<li><a href="" 
    ng-class="{active:(num==1 && activityState==true)}"
    ng-click="chooseNumber(1, $event)">1</a></li>
<li><a href=""
    ng-class="{active:(num==2 && activityState==true)}"
    ng-click="chooseNumber(2, $event)">2</a></li>
<li><a href=""
    ng-class="{active:(num==1 && activityState==true)}"
    ng-click="chooseNumber(1, $event)">3</a></li>
</ul>

<p><a href="/#/second">האם אתה צודק בניחוש?</a></p>

pages/second.html

בטמפלייט השני, כל מה שנותר לעשות זה להציג את התוצאה.


<h1>התוצאה: {{ result }}</h1>

 

מדריכי AngularJS

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

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

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

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

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

השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.

הוסף תגובה חדשה

 

 

ענה על השאלה הפשוטה הבאה כתנאי להוספת תגובה:

מתי הוקמה המדינה?

 

תמונת המגיב

ג'וני בתאריך: 14.01.2017

קודם כל, תודה על המדריך המפורט והמובן.
רציתי לשאול אם קיים הבדל כלשהו אם
אני אעביר את המידע בין הקונטרולרים באמצעות
באמצעות $routeParams לבין ה$service?

תמונת המגיב

יוסי בן הרוש בתאריך: 15.01.2017

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