如何将自定义指令属性传递给Angular 1.5中的自定义指令子元素?

时间:2019-01-07 16:36:49

标签: javascript angularjs angularjs-directive

我目前正在尝试将验证指令传递给自定义元素指令。但是我一直在努力使其工作,因为当我使用绑定到控制器时它应该接收模型作为输入。

我必须假定不能升级到Angular的最新版本,因此1.5是限制,同时我不能编辑验证指令。 我以为transclude会有所帮助,但是具有指令属性似乎显得不太有希望。 以下代码应该做的是验证输入元素上的vm.model。

这是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 :(得分:0)

一种基于组件属性向模板添加指令的方法是使用模板属性的函数形式:

<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函数复制属性并将其用于模板文字中。

有关更多信息,请参见