Передайте значение для компиляции функции в директиве

0

Я пытаюсь сделать некоторые общие поля и использовать директиву для этого. Например, в 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 недоступна в функции компиляции. Есть ли какая-то возможность решить эту проблему?

В настоящее время я передаю в качестве атрибута тип "массив", но это не приемлемый вариант.

Теги:

1 ответ

0
Лучший ответ

Прочитав некоторый материал об Угловом, мне удалось найти решение. К сожалению, в моем приложении большинство бизнес-логики было в контроллерах, что неверно в соответствии с руководствами по стилям:

Angular 1 Style Guide от John Papa (бизнес-логика)

Angular 1 Style Guide от Todd Motto (бизнес-логика)

Поэтому я переместил свою бизнес-логику на контроллеры, а затем я смог получить требуемые данные в директиве от службы. Чтобы показать это, я подготовил небольшой демонстрационный пример:

Ссылка на Plunker

Объяснение кода: Во-первых, я определил службу, которая должна получить требуемые данные:

(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 директивы:

Изображение 174551

Обратите внимание: я не уверен, правильно ли использовать сервис, завод или поставщик для предоставления данных. Я только показал, как это возможно при обслуживании. Я думаю, с фабрикой и провайдером логика такая же.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню