Как передать пользовательский атрибут директивы в дочерний элемент пользовательской директивы в Angular 1.5? - PullRequest
0 голосов
/ 07 января 2019

В настоящее время я пытаюсь передать директиву валидации в директиву пользовательского элемента. Но я изо всех сил пытаюсь заставить его работать, так как он должен получать модель в качестве входа, пока я использую привязку к контроллеру.

Я должен предположить, что я не могу перейти на более новую версию Angular, поэтому ограничение 1.5 является ограничением, а также тот факт, что я не могу редактировать директиву проверки. Я думал, что transclude помог бы, но с атрибутом директивы это выглядит не так многообещающе. Следующий код должен проверить vm.model на элементе input.

Вот HTML:

  <body ng-controller="MainCtrl">
    <div class="myClass">
      <my-custom-directive data-placeholder="No text"
                           data-id="myModel.id"
                           data-model="myModel.text" 
                           not-editable-directive-attribute >
      </my-custom-directive>
    </div>
  </body>

А вот и app.js:

var myTemplate = '<div class="myContainer">' +
  '<input class="myInput"' +
  '       ng-mousedown="$event.stopPropagation();"' +
  '       ng-show="vm.isFocused"' +
  '       ng-model="vm.model"' +
  '       ng-change="vm.onChange()"' +
  '       type="text">' +
  '<span ng-show="!vm.isFocused">{{vm.model}}</span>' +
  '<span ng-show="!vm.isFocused && !vm.model && vm.placeholder">{{vm.placeholder}}</span>' +
  '</div>';

app.controller('MainCtrl', function($scope) {
  $scope.myModel = {
    id: 'test',
    text: 'this is text'
  };
});
app.directive('myCustomDirective', ['$timeout', function($timeout) {
  return {
    restrict: 'E',
    replace: true,
    template: myTemplate,
    controllerAs: 'vm',
    bindToController: {
      id: '@',
      model: '=',
      onChange: '&',
      placeholder: '@'
    },
    scope: {},
    controller: angular.noop,
    link: function(scope, element) {
      var input = element.find('input')[0];
      var spans = Array.from(element.find('span'));

      var vm = scope.vm;
      vm.isFocused = false;

      vm.focus = function() {
        vm.isFocused = true;
        scope.$applyAsync(function() {
          $timeout(function() {
            input.focus();
            input.select();
          });
        });
      };

      spans.forEach(span => span.addEventListener('click', vm.focus));
    }
  };
}]);
app.directive('notEditableDirectiveAttribute', [function() {
  return {
    require: 'ngModel',
    link: function(scope, elem, attrs, ctrl) {
      ctrl.$validators.myCustomDirectiveAttribute = function(modelValue, viewValue) {
        if (viewValue) {
          return viewValue.indexOf('e') < 0;
        }

        return false;
      };
    }
  };
}]);

Я создал планер, чтобы прояснить ситуацию: http://plnkr.co/edit/auminr?p=preview

Таким образом, нажав на элемент span, я должен иметь возможность редактировать текст, а директива должна подтвердить его (в данном конкретном случае проверьте, содержит ли он букву «e»).

Это вообще возможно или я борюсь с ветряными мельницами?

1 Ответ

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

Один из подходов к добавлению директив в шаблоны на основе атрибутов компонента заключается в использовании функциональной формы свойства шаблона:

<my-custom-directive data-placeholder="No text"
                     model="vm.data" 
                     custom="not-editable-directive-attribute" >
</my-custom-directive>
app.directive("myCustomDirective", function() {
    return {
        template: createTemplate,
        scope: {},
        //...
    });
    function createTemplate(tElem, tAttrs) {
        var placeholder = tAttrs.placeholder;
        var model = tAttrs.model;
        var custom = tAttrs.custom;
        return `
            <input placeholder=${placeholder}
                   ng-model=${model}
                   ${custom} />
        `;
    }
})

Функция createTemplate копирует атрибуты и использует их в литерале шаблона.

Для получения дополнительной информации см.

...