در قسمت قبل با انگولار آشنا شدیم و به بعضی ویژگیهاش اشاره کردیم. توی این مطلب قراره با هم یه پروژه فوتبالی با انگولار اجرا کنیم. تمرکز اصلی روی کنترلرها هست، بنابراین تنها به توضیح اجمالی سایر قسمتها اکتفا میکنیم تا در بخش خودشون مفصل به اونها بپردازیم.
پروژه فوتبالی که قصد پیاده سازیش رو با Angular.js داریم، قرار هست آمار کلی درباره تیمهای فوتبال (در اینجا تیمهای فوتبال انگلیس) رو به همراه ویژگی جستجو و چینش به کاربرمون ارائه بده. اگر بخواهیم طبق مطلب قبلی پیش بریم قدم اول : تامین محتوا
برای سهولت کار و تمرکز روی کار در اینجا از یک آرایه استفاده می کنیم و در مطالب بعدی اطلاعات رو با سرور همگام میکنیم. آرایه ما به شکل زیر هست :
[ {'name': 'Arsenal', 'pic':'Arsenal'}, {'name': 'Everton', 'pic':'Everton'}, {'name': 'Aston Villa', 'pic':'Aston_Villa'}, {'name': 'Tottenham Hotspur', 'pic':'Tottenham_Hotspur'}, {'name': 'Blackburn Rovers', 'pic':'Blackburn_Rovers'}, {'name': 'Bolton Wanderers', 'pic':'Bolton_Wanderers'}, {'name': 'Burnley FC', 'pic':'Burnley_FC'}, {'name': 'Cardiff City', 'pic':'Cardiff_City'}, {'name': 'Celtic', 'pic':'Celtic'}, {'name': 'Nottingham Forest', 'pic':'Nottingham_Forest'}, {'name': 'Coventry City', 'pic':'Coventry_City'}, {'name': 'Derby County', 'pic':'Derby_County'}, {'name': 'England', 'pic':'England'}, {'name': 'Birmingham City', 'pic':'Birmingham_City'}, {'name': 'Norwich City', 'pic':'Norwich_City'}, {'name': 'Portsmouth FC', 'pic':'Portsmouth_FC'}, {'name': 'Queens Park Rangers', 'pic':'Queens_Park_Rangers'}, {'name': 'British', 'pic':'British'}, {'name': 'Reading', 'pic':'Reading'}, {'name': 'Chelsea', 'pic':'Chelsea'}, {'name': 'Watford FC', 'pic':'Watford_FC'} ]
همونطور که میبینید آرایه تشکیل شده از نام تیم و تصویر پرچم اون تیم که قرار هست توسط انگولار از این اطلاعات استفاده کنیم.
قدم دوم : کنترلر
برای اینکه بین اطلاعات موجود و رابط کاربری تبادل اطلاعات صورت بگیره نیاز داریم پلی ایجاد کنیم. ساخت این پل یکی از وظایف کنترلر هست :
var teamsApp = angular.module('teamsApp', []);
قطعه کد بالا در برگیرنده تمامی بخش هایی که در معرفی انگولار نام بردیم هست. ابتدا ما یک واحد (module) برای انگولار تعریف کردیم، “angular.module” و نام teamsApp رو بهش اختصاص دادیم. از این نام در زمان فراخوانی واحد(module) در HTML بهره میبریم. در پروژهها اغلب ما چند واحد (module) تعریف میکنیم و نیاز داریم هر کدوم رو برای بخشی جدا فراخوانی کنیم، پس نامگذاری صحیح بسیار میتونه مفید باشه. در قسمت بعد که فعلا در این پروژه خالی هست Dependency Injection یا تامین وابستگیها رو قرار میدیم، از جمله ارتباط با سرور و …
خب.ما الان واحد (module) شخصی خودمون رو در اختیار داریم. حالا وقتشه اولین کنترلر رو تعریف کنیم :
teamsApp.controller('TeamsListCtrl', function ($scope) { $scope.teams = [ {'name': 'Arsenal', 'pic':'Arsenal'}, {'name': 'Everton', 'pic':'Everton'}, {'name': 'Aston Villa', 'pic':'Aston_Villa'}, {'name': 'Tottenham Hotspur', 'pic':'Tottenham_Hotspur'}, {'name': 'Blackburn Rovers', 'pic':'Blackburn_Rovers'}, {'name': 'Bolton Wanderers', 'pic':'Bolton_Wanderers'}, {'name': 'Burnley FC', 'pic':'Burnley_FC'}, {'name': 'Cardiff City', 'pic':'Cardiff_City'}, {'name': 'Celtic', 'pic':'Celtic'}, {'name': 'Nottingham Forest', 'pic':'Nottingham_Forest'}, {'name': 'Coventry City', 'pic':'Coventry_City'}, {'name': 'Derby County', 'pic':'Derby_County'}, {'name': 'England', 'pic':'England'}, {'name': 'Birmingham City', 'pic':'Birmingham_City'}, {'name': 'Norwich City', 'pic':'Norwich_City'}, {'name': 'Portsmouth FC', 'pic':'Portsmouth_FC'}, {'name': 'Queens Park Rangers', 'pic':'Queens_Park_Rangers'}, {'name': 'British', 'pic':'British'}, {'name': 'Reading', 'pic':'Reading'}, {'name': 'Chelsea', 'pic':'Chelsea'}, {'name': 'Watford FC', 'pic':'Watford_FC'} ]; });
اگر انتظار داشتید با حجم زیادی کد روبرو بشید، متاسفم، در حال حاظر همین مقدار کافی هست و عملکر خوبی هم داره.
ما توسط این کد به انگولار میگیم کنترلری با نام TeamsListCtrl تعریف کنه و به اون اجازه دسترسی به $scope بده. اگر خود کنترلر رو یک پل در نظر بگیرید، $scope مثل وسایل نقلیه روی پل عمل میکنه که وظیفه جابجایی رو بر عهده دارند. بنابراین اطلاعاتی که نیاز داریم به رابط کاربری منتقل بشه رو به $scope پاس میدیم که شامل آرایهای از json هست. در اینجا اسمی که برای وسیله نقلیه ($scope) انتخاب کردیم “teams” هست، با همین نام میتونیم اون رو فراخوانی کنیم.این فایل رو با نام “controllers.js” ذخیره می کنیم.
قدم سوم : رابط کاربری
باز هم برای سهولت در کار و دور نشدن از بحث از بوت استرپ استفاده کردیم. اگر با بوت استرپ آشنایی ندارید و یا در حال حاضر نسخهای از اون رو ندارید پیشنهاد میکنم از آدرس cdn اون استفاده کنید و یک صفحه خالی مثل من ایجاد کنید، همچنین کتابخانه انگولار رو هم میتونید از اینجا بارگذاری کنید. زمانی که این مطلب رو مینویسم، آخرین نسخه پایدار انگولار “۱٫۳٫۱۴” هست و ما به این کتابخانه نیاز داریم. در آخر هم فایل کنترلری که ایجاد کردیم رو در پروژه قرار میدیم. چیزی شبیه به کد زیر
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Search teams</title> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.2/cosmo/bootstrap.min.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script> <script src="controllers.js"></script> </head> <body> </body> </html>
قدم بعدی قرار دادن صفتهای (attribute) مرتبط با انگولار هست. برای اینکه انگولار متوجه بشه قصد داریم از کدوم واحد (module) استفاده کنیم، از “ng-app” استفاده میکنیم. در حال حاضر تنها ماژولی که داریم “teamsApp” هست. پس طبق کد زیر تغییرات رو اعمال میکنیم :
<html lang="en"> <html lang="en" ng-app="teamsApp">
حالا تمام صفحه تحت پوشش ماژول “teamsApp” هست. به عبارت دیگه ما هر کنترلری که صدا بزنیم، داخل ماژول “teamsApp” دنبالش میگرده.
وقت استفاده از کنترلر رسید. کنترلرها در انگولار با ng-controller فراخوانی میشن. پس تگ body رو به شکل زیر تغییر میدیم تا کنترلر رو فراخوانی کنه :
<body ng-controller="TeamsListCtrl">
ارتباط بین ماژول و رابط کاربری هم برقرار شد.
قدم نهایی : نمایش اطلاعات
در معرفی انگولار اشاره کردیم که از قالبها پشتیبانی خوبی داره. ما در این مطلب از ابتداییترین پشتیبانی قالب انگولار استفاده میکنیم :
<table class="table-striped col-md-12 col-lg-12 col-xs-12"> <thead> <tr> <th class="text-center" colspan="3"> <div class="page-header"> <h1>Search teams with Angular</h1> </div> </th> </tr> <tr> <td class="form-group" colspan="2"> <input type="text" placeholder="Search Here . . ." class="form-control col-md-12" ng-model="query"> </td> <td class="form-group" colspan="1"> <select class="form-control" ng-model="orderProp"> <option value="name">name</option> <option selected="true">default</option> </select> </td> </tr> </thead> <tbody> <tr ng-repeat="team in teams | filter:query | orderBy:orderProp"> <td width="50" class="text-center">{{$index + 1}}</td> <td>{{team.name}}</td> <td class="text-center"><img src="img/teams/{{team.pic}}.png" class="img-rounded" width="50" height="50" /></td> </tr> </tbody> </table>
توی کد بالا کدهایی دیدیم که html نیست ولی بسیار قابل فهم هست :
<tr ng-repeat="team in teams | filter:query | orderBy:orderProp">
ng-repeat بخشی از قالب که نیاز داریم داخل حلقه قرار بگیره رو معلوم میکنه. Team in teams کاملا مثل حلقه for – in در جاوااسکریپت عمل میکنه و به ترتیب هر یک از آبجکت های داخل teams رو در هر بار اجرا به team میکنه. برای دسترسی به بخش های داخل هر آبجکت مثل JSON عمل میکنیم و از {{team.name}} یا {{team.pic}} استفاده میکنیم. دو تا المنت باقی موندن. یک ورودی متن و یک باکس انتخاب
<input type="text" ng-model="query"> <tr ng-repeat="team in teams | filter:query | orderBy:orderProp">
به انگولار اطلاع میده که میانبری بین این ورودی متن و $scope که در کنترلر تعریف کردیم ایجاد کنه و مشخصات رو طبق این ورودی فیلترگذاری کنه. با filter:query هم به انگولار گفتیم که اگر ورودی از ng-model با نام query داشتیم، فیلتر رو اعمال کنه.
<select class="form-control" ng-model="orderProp"> orderBy:orderProp
کد بالا هم دقیقا مثل ورودی مت عمل می کنه با این تفاوت که فیلترگذاری صورت نمیگیره و تنها نحوه چینش رو تغییر دادیم. این یک مثال بسیار ساده بود که شما میتونید با کمی دقت به کدها و توضیحات، مثال های متعددی پیادهسازی کنید.
این که فقط یک جدول ساده بود، پس آمارش کو؟! 🙂
درود.
ممنون که ما رو همراهی می کنید.
دوست عزیز اگر به عنوان مطلب عنایت بفرمایید “آمار فوتبال با انگولار – قسمت اول” این بخش اول هست و سلسله وار ،تا انتهای پروژه ادامه خواهد داشت.