ایجاد برنامه آزمون با استفاده از MVC در AngularJS

چهارشنبه 4 آذر 1394

محبوبیت AngularJS بین برنامه نویسان رو به افزایش است. این یک فریم ورک جاوا اسکریپتی برای برای ایجاد برنامه های سازمان یافته و قابل نگهداری است. این مقاله نشان می دهد که چگونه با سرعت می توان یک برنامه ساخت یافته وب ایجاد کرد.

ایجاد برنامه آزمون با استفاده از MVC در AngularJS

برای درک بهتر این مقاله باید با اصول اولیه AngularJS آشنا باشید.

این برنامه ساختار بسیار ساده ای دارد، در صفحه اول آن یک سوال چهار گزینه ای، یک دکمه ارسال پاسخ و قسمت امتیازات بدست آمده وجود دارد. برای سادگی کار هیچ بانک اطلاعاتی ای در نظر نگرفته ایم و به جای آن مجموعه ای از سوالات را در برنامه خود تعریف می کنیم.

برای ایجاد این برنامه به دو فایل HTML نیاز داریم که یکی صفحه HTML اصلی است و دیگری قالب سوالات را در بر می گیرد. همچنین به فایل app.js نیز نیاز داریم که منطق برنامه ما می باشد.

صفحه HTML اصلی به صورت زیر تعیین می شود:

<!DOCTYPE html>
<html ng-app="quizApp">
<head>
  <meta charset="utf-8" />
  <title>QuizApp</title>
  <link rel="stylesheet" href="style.css" />
  <script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
  <script src="app.js"></script>
</head>

<body dir="rtl">
  <div class="container">
    <h1 class="title">سوالات برنامه نویسی</h1>
    <quiz/>
  </div>
</body>

</html>

دو مطلب جالب در اینجا وجود دارد که یکی صفت ng-app و دیگری تگ quiz می باشد. ما در اینجا یک دستور سفارشی برای تگ quiz بعد تعریف کرده ایم.

حالا در این مرحله باید template یا قالب را طراحی کنیم. قالب سوالات در تگ Quiz که در بالا ذکر شد جایگزین می شود. template شامل دو بخش است: یکی زمانی که آزمون در حال اجرا است و یکی زمانی که برنامه آزمون در ابتدا لود می شود.

<div class="quiz-area" ng-show="inProgress">
</div>
 
<div class="intro" ng-show="!inProgress">
	<p>Welcome to the QuizApp</p>
	<button id="startQuiz" ng-click="start()">Start the Quiz</button>
</div>

همانطور که می دانید، ما در اینجا از دو دستور ساخته شده استفاده کردیم: که یکی ng-show و دیگری ng-click می باشد. inprogress و ( )start در ادامه توضیح داده خواهند شد.

در بخش آزمون، یا یک سوال را نشان می دهیم و یا پیغامی را زمانی که آزمون به اتمام رسیده است، نمایش می دهیم. همچنین بخشی برای نمره بدست آمده نیز قرار داده ایم.

<div class="quiz-area" ng-show="inProgress">
	<div ng-show="!quizOver">
	</div>
 
	<div ng-show="quizOver">
		<h2>Quiz is over</h2>
		<button ng-click="reset()">Play again</button>
	</div>
 
	<div id="score">
	</div>
</div>

در app.js یک دستور سفارشی با نام quiz ایجاد کرده ایم که به صورت زیر می باشد:

var app = angular.module('quizApp', []);
 
app.directive('quiz', function() {
    return {
	restrict: 'AE',
	scope: {},
	templateUrl: 'template.html',
	link: function(scope, elem, attrs) {
	    //TODO
	}
    }
});

حالا باید متدهایی برای شروع آزمون، دریافت یک سوال و کنترل جواب بنویسیم:

var app = angular.module('quizApp', []);
 
app.directive('quiz', function(quizFactory) {
	return {
		restrict: 'AE',
		scope: {},
		templateUrl: 'template.html',
		link: function(scope, elem, attrs) {
			scope.start = function() {
			};
 
			scope.getQuestion = function() {
			};
 
			scope.checkAnswer = function() {
			};
		}
	}
});

حالا این متدها را پیاده سازی می کنیم:

scope.start = function() {
	scope.id = 0;
        scope.quizOver = false;
	scope.inProgress = true;
	scope.getQuestion();
};

در اینجا باید یک سوال دریافت کنیم و برای این کار احتیاج به منبعی برای سوالات داریم. پس یک منبع برای سوالات تعیین می کنیم. این منبع سوالات زمانی که id یک سوال درخواست می شود سوال مورد نظر را برمی گرداند.

app.factory('quizFactory', function() {
	var questions = [
		{
		    question: "1- برای سربارگذاری یک عملگر، در نام متد  Staticو Public باید از چه کلمه کلیدی استفاده کرد؟",
		    options: ["Sealed", "Interface", "Operator", "Class"],
		    answer: 2
            
		},
		{
		    question: "2- چه نوع کلاس‌هایی که نمی‌توان آنها را به عنوان کلاس‌ پایه برای دیگر کلاس‌ها مورد استفاده قرارداد؟",
		    options: ["Sealed", "Abstract", "Interface", "Class"],
			answer: 0
		},
		{
		    question: "3- کلاس‌هایی که نمی‌توان هیچ شیئ را از آنها نمونه‌سازی کرد و حتما باید به عنوان کلاس پایه برای دیگر کلاس‌ها مورد استفاده قرار گیرند.",
		    options: ["Solution", "Console", "Class", "Abstract"],
			answer: 3
		},
		{
		    question: "4- براي ارتباط با يك شي از كدام موارد زير استفاده ميشود",
		    options: ["متد ها و خاصيت ها", "خاصيت ها", "متد ها", "هيچكدام"],
			answer: 0
		},
		{	
		    question: "10- براي اينكه يك متغير فقط توسط متد هايي كه درون كلاس قرار دارند قابل دسترسي باشد از چه كلمه كليدي استفاده ميكنيم",
		    options: ["public ", " private", "local", "static"],
			answer: 1
		}
	];

حالا در اینجا متد ( )getQuestion را در دستور سفارشی Quiz پیاده سازی می کنیم:

scope.getQuestion = function() {
	var q = quizFactory.getQuestion(scope.id);
	if(q) {
		scope.question = q.question;
		scope.options = q.options;
		scope.answer = q.answer;
	} else {
		scope.quizOver = true;
	}
};

حالا به template برمی گردیم و جزییات را پر می کنیم:

<div class="quiz-area" ng-show="inProgress">
	<div ng-show="!quizOver">
		<h2 id="question">{{question}}</h2>
		<ul id="options">
			<li ng-repeat="option in options">
				<label>
					<input type="radio" name="answer" value="{{option}}">
					{{option}}
				</label>
			</li>
		</ul>
		<button ng-click="checkAnswer()" ng-show="answerMode">ارسال پاسخ</button>

		<div ng-show="!answerMode">
			<button ng-click="nextQuestion()" class="next-question">سوال بعدی</button>
			<span ng-show="correctAns">صحیح است!</span>
			<span ng-show="!correctAns">پاسخ نادرست است.</span>
		</div>
	</div>

	<div ng-show="quizOver">
		<h2>زمان امتحان تمام شد</h2>
		<button ng-click="reset()">دوباره شروع کنید</button>
	</div>

	<div id="score">
		Score: {{score}}
	</div>
</div>

متد ( )checkAnswer باید گزینه های انتخاب شده را با پاسخ های صحیح مقایسه کند، همچنین به answerMode نیاز داریم بنابراین یا گزینه ها و یا نتیجه سوال فعلی را نشان می دهیم. در  زمانی که کاربر روی "سوال بعدی" کلیک می کند، باید برنامه سوال بعدی را نشان دهد. متد ( )nextQuestion این کار را انجام می دهد. وبه صورت زیر می باشد:

var app = angular.module('quizApp', []);

app.directive('quiz', function(quizFactory) {
	return {
		restrict: 'AE',
		scope: {},
		templateUrl: 'template.html',
		link: function(scope, elem, attrs) {
			scope.start = function() {
				scope.id = 0;
				scope.quizOver = false;
				scope.inProgress = true;
				scope.getQuestion();
			};

			scope.reset = function() {
				scope.inProgress = false;
				scope.score = 0;
			}

			scope.getQuestion = function() {
				var q = quizFactory.getQuestion(scope.id);
				if(q) {
					scope.question = q.question;
					scope.options = q.options;
					scope.answer = q.answer;
					scope.answerMode = true;
				} else {
					scope.quizOver = true;
				}
			};

			scope.checkAnswer = function() {
				if(!$('input[name=answer]:checked').length) return;

				var ans = $('input[name=answer]:checked').val();

				if(ans == scope.options[scope.answer]) {
					scope.score++;
					scope.correctAns = true;
				} else {
					scope.correctAns = false;
				}

				scope.answerMode = false;
			};

			scope.nextQuestion = function() {
				scope.id++;
				scope.getQuestion();
			}

			scope.reset();
		}
	}
});

همانطور که مشاهده کردید با چند خط جاوا اسکریپت یک برنامه ساده ولی کاملا عملیاتی ایجاد کردیم. که خروجی آن به صورت زیر می باشد:

شروع آزمون:

شروع سوالات:

ارسال پاسخ:

و روال به همین ترتیب ادامه دارد، در پایان سوالات صفحه زیر نشان داده می شود که آزمون تمام شده و می توانید آن را دوباره شروع کنید:

آموزش angular

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید