Создание своих директив

Последнее обновление: 26.04.2017

AngularJS содержит множество встроенных директив, но их функциональности не всегда достаточно. Иногда необходимо применить более комплексное решение, чем стандартные элементы html, использующие встроенные директивы.

Создадим свою директиву. Для этого в папке js создадим новый файл answerList.js со следующим содержанием:

questApp.directive("answerList", function () {
	return function (scope, element, attrs) {
		var data = scope[attrs["answerList"]];
		if (angular.isArray(data.answers)) {
			var ulElem = angular.element("<ul>");
			element.append(ulElem);
			for (var i = 0; i < data.answers.length; i++) {
				var liElem = angular.element('<li>');
				liElem.append(angular.element('<p>').text(data.answers[i].text));
				ulElem.append(liElem);
			}
		}
	}
});

В итоге весь проект будет выглядеть следующим образом:

создание директив в AngularJS

Разберем директиву. Директива создается с помощью метода Module.directive(). В данном случае модулем является questApp, объявленный в другом файле. Данный метод принимает два параметра: название директивы и функцию, которая собственно и создает директиву.

В качестве названия используется "answerList". Согласно соглашениям об именовании любая буква в верхнем регистре расценивается как начало нового слова, которое будет отделено от предыдущего дефисом. То есть для AngularJS "answerList" будет представлять "answer-list" или "answer-List".

В функцию создания директивы передается три параметра:

  • scope - объект $scope, установленный в контроллере

  • element - элемент, к которому применяется директива

  • attrs - коллекция атрибутов в виде пары ключ-значение, где ключом является название атрибута

Например, далее мы будем передавать объект $scope.question в эту директиву:

<div answer-list="question"></div>

В данном случае элементом является элемент div, а коллекция атрибутов будет содержать единcтвенный атрибут - директиву answer-list. А question - это объект $scope.question

И в строке var data = scope[attrs["answerList"]]; мы как раз получим этот объект question, переданный в директиву. Но фактически мы могли пойти и другим путем - сразу получить данный объект без использования коллекции атрибутов:

var data = scope.question;

Далее мы можем уже обращаться к объектам, которые заключены внутри $scope.question: data.answers. Но перед обращением мы проверяем, является ли нужный нам объект массивом: angular.isArray(data.answers)

Дальше в директиве идет создание html-элементов и перебор элементов внутри массива data.answers. Для создания элементов применяется функция angular.element(), а для добавления созданных элементов в другой - метод append()

Применим директиву на главной странице:

<!doctype html>
<html ng-app="questApp">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/mystyles.css" />
</head>
<body>
<div  ng-controller="QuestionController">
<div class="quest">
<h3>{{question.text}}</h3>
<p>{{question.author}} </p> <p><i>{{question.date}}</i></p>
</div>
<h3>Ответы</h3>
<div answer-list="question"></div>
</div>
<script src="js/lib/angular.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers/QuestionController.js"></script>
<script src="js/answerList.js"></script>
</body>
</html>
Создание директив в AngularJS

Теперь изменим директиву, чтобы веб-страница получилась такой же как и в прошлых темах:

questApp.directive("answerList", function () {
	return function (scope, element, attrs) {
		
		var data = scope[attrs["answerList"]];
		
		if (angular.isArray(data.answers)) {
			var divElem = angular.element("<div>").addClass("answers");
			element.append(divElem);
			for (var i = 0; i < data.answers.length; i++) {
				var answerElem = angular.element('<div>').addClass("answer");
				var voteElem = angular.element('<div>').addClass("vote");
				
				var voteUpElem = angular.element('<a>').addClass("vote-up");
				voteElem.append(voteUpElem);
				var rateElem = angular.element('<span>').addClass("rate").text(data.answers[i].rate);
				voteElem.append(rateElem);
				var voteDownElem = angular.element('<a>').addClass("vote-down");
				voteElem.append(voteDownElem);
				answerElem.append(voteElem);
				
				answerElem.append(angular.element('<b>').text(data.answers[i].text));
				answerElem.append(angular.element('<p>').text(data.answers[i].author));
				var iElem =angular.element('<i>').text(data.answers[i].date);
				var dateElem = angular.element('<p>').append(iElem);
				answerElem.append(dateElem);
				divElem.append(answerElem);
			}
		}
	}
});

И наша страница станет более привычной:

Делаем директиву в AngularJS
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850