Я пытаюсь сделать некоторые общие поля и использовать директиву для этого. Например, в HTML-коде я определяю:
<div def-field="name"></div>
<div def-field="surname"></div>
<div def-field="children"></div>
Это поле может быть двух типов: либо простой элемент (как первые два), либо список элементов (как третий). Переменная области содержит определение всех полей и их типов. Для этого я создал директиву "def-field":
app.directive("defField", function($compile, $parse, $http) {
restrict: 'A', // only for attributes
scope : true,
return {
restrict: 'A', // only for attributes
scope : true,
compile: function compile(tElement, tAttributes) {
//here I need to detect, which type of field is it.
//if it is array, I need to execute the compile code
if(fieldType === 'array') {
//execute secial code for compile furnction
}
}
if(fieldType === 'array') {
//return for array
var returnValue = {pre : linkFunction};
} else {
//return for normal type
var returnValue = {
pre : linkFunction,
post: function(scope, element, attrs){
$compile(element.parent())(scope);
}
};
}
return returnValue;
}
Проблема в том, что мне нужно получить fieldType из переменной области видимости, а переменная scope недоступна в функции компиляции. Есть ли какая-то возможность решить эту проблему?
В настоящее время я передаю в качестве атрибута тип "массив", но это не приемлемый вариант.
Прочитав некоторый материал об Угловом, мне удалось найти решение. К сожалению, в моем приложении большинство бизнес-логики было в контроллерах, что неверно в соответствии с руководствами по стилям:
Angular 1 Style Guide от John Papa (бизнес-логика)
Angular 1 Style Guide от Todd Motto (бизнес-логика)
Поэтому я переместил свою бизнес-логику на контроллеры, а затем я смог получить требуемые данные в директиве от службы. Чтобы показать это, я подготовил небольшой демонстрационный пример:
Объяснение кода: Во-первых, я определил службу, которая должна получить требуемые данные:
(function () {
"use strict";
angular.module("dirExampleApp").service("directiveService", ["$timeout", function ($timeout) {
var self = this;
self.getObjectData = function () {
return $timeout(function () {
var responseFromServer = {
firstName: {
value: "firstValue"
},
secondName: {
value: "secondValue"
},
thirdName: {
value: "thirdValue"
},
fourthName: {
value: "fourthValue"
}
};
self.content = responseFromServer;
}, 300);
};
}]);
})();
Затем я могу ввести эту службу и использовать ее в моей директиве либо в функции компиляции, либо в prelink или postlink:
(function () {
"use strict";
angular.module("dirExampleApp").directive("dirExample", ["$log", "directiveService", function ($log, directiveService) {
return {
restrict: "A",
template: "<h3>Directive example!</h3>",
compile: function (tElem, tAttrs) {
var fieldName = tAttrs.dirExample;
$log.log('Compile function: Field with name: ' + fieldName +
' and sevice provided the following data: ' +
directiveService.content[fieldName].value);
return {
pre: function (scope, iElem, iAttrs) {
var fieldName = iAttrs.dirExample;
$log.log('Prelink function: Field with name: ' + fieldName +
' and sevice provided the following data: ' +
directiveService.content[fieldName].value);
},
post: function (scope, iElem, iAttrs) {
var fieldName = iAttrs.dirExample;
$log.log('Postlink function: Field with name: ' + fieldName +
' and sevice provided the following data: ' +
directiveService.content[fieldName].value);
}
};
}
};
}]);
})();
В результате, некоторые директивы создаются. Это ведение журнала показывает, что необходимые данные были успешно извлечены из службы в функции компиляции, prelink и postlink директивы:
Обратите внимание: я не уверен, правильно ли использовать сервис, завод или поставщик для предоставления данных. Я только показал, как это возможно при обслуживании. Я думаю, с фабрикой и провайдером логика такая же.