Динамически установленный атрибут для дочерней директивы в Angularjs - PullRequest
0 голосов
/ 11 января 2019

Я хочу динамически установить атрибуты для дочерней директивы.
Но я не могу этого сделать.

В примере я хочу установить атрибут name со значением John.

UPD: в этом случае я не могу определить точный набор атрибутов. И мне нужно определить их динамически. Например, это часть сторонней библиотеки.

angular.module('app', []);

angular.module('app')
  .directive('wrapper', wrapper);

angular.module('app')
  .directive('inWrapper', inWrapper);

angular.bootstrap(
  document.getElementById('root'), ['app']
);

function wrapper() {
  return {
    transclude: true,
    template: '<div ng-transclude></div>',
    link: function linkFn(scope, element, attrs, ctrl,  transcludeFn) {
      transcludeFn(
        scope,
        function(clone) {
          clone.find('in-wrapper').attr('name', 'John');
        }
      );
    }
  }
}

function inWrapper() {
  return {
    scope: {
      name: '@'
    },
    template: 'Hello, {{name}}',
    link: function linkFunc(scope) {
      if (!scope.name) {
        scope.name = 'Empty';
      }
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div id="root">
  <wrapper>
    <in-wrapper></in-wrapper>
  </wrapper>
</div>

Ответы [ 2 ]

0 голосов
/ 12 января 2019

Я пытался установить атрибуты динамически, но безуспешно.
Вместо этого я предлагаю предоставить данные для атрибутов в области элементов напрямую.
В примерах кода я модифицировал элементы внутри функции transclude. И предоставил данные для элементов атрибута в контроллере. Код не идеален. Только для демонстрации идеи.

P.S. Спасибо @CodeMonkey за критику оригинальной идеи

angular.module("app", []);

angular.module("app").directive("wrapper", wrapper);

angular.module("app").directive("inWrapper", inWrapper);

angular.bootstrap(document.getElementById("root"), ["app"]);

function wrapper() {
  return {
    restrict: "E",
    transclude: true,
    controller: function linkFn($scope, $element, $attrs, $transclude) {
      var transcludedContent, transclusionScope,
        statuses = [
          'danger',
          'success',
          'info'
        ];
      status = 0;
      $transclude(function(clone, scope) {
        $element.append(clone);
        transcludedContent = clone;
        transclusionScope = scope;
        for (var i = 0, ii = clone.length; i < ii; i++) {
          var node = clone[i];
          if (node.nodeType !== 3 ||
            node.nodeValue.trim()) {
            node.classList.add(statuses[status]);
            status++;
          }
        }
      });
      // find scope for angulars element and provide data
      var elements = $element.find("in-wrapper");
      for (var i = 0, ii = elements.length; i < ii; i++) {
        var isolateScope = angular.element(elements[i]).isolateScope();
        isolateScope.name = 'World' + isolateScope.$id;

      }

    }
  };
}

function inWrapper() {
  return {
    scope: {
      name: "@"
    },
    template: '<div>Hello, <span ng-bind="name"></span></div>'
  };
}
.danger {
  color: #ff0000;
}

.success {
  color: #00ff00;
}

.info {
  color: #0000ff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div id="root">
  <wrapper>
    <in-wrapper></in-wrapper>
    <in-wrapper></in-wrapper>
    <in-wrapper></in-wrapper>
  </wrapper>
</div>
0 голосов
/ 11 января 2019

Вы должны иметь возможность связать атрибут с переменной области видимости. Если вы говорите о разработке директивы самостоятельно, вы можете определить переменные области видимости контроллера как «=», и они будут двунаправленно связаны со значением, передаваемым атрибуту. Обратитесь к AngularJS: Руководство разработчика для получения дополнительной информации.

Вы также можете назначить значение атрибута, используя аннотацию {{...}}, чтобы вставить переменную области непосредственно в разметку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...