Почему я не могу использовать функцию $ set угловой директивы angular для установки ngPattern, ngMinlength и ngMaxlength?

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

HTML:

<div ng-controller='CtrlCtrl as ctrlr'>  
  <input account />
  <button ng-disabled='ctrlr.isValid()'>Click</button>
</div>

выглядеть так:

Цель:

<div ng-controller='CtrlCtrl as ctrl'>  
 <input type='text' name='derp_herp' ng-model='ctrlr.goal'
   ng-maxlength='10' ng-minlength='3' ng-required='true'
   ng-pattern='/^\d+$/' ng-focus='ctrlr.action()' ng-blur='ctrlr.validate()'
   ng-change='ctrlr.checkValid()'
 />
</div>

БЕЗ этого:

app.directive('accounts', [function() {
  return {
    restrict: 'A',
    scope: {},
    transclude: true,
    templateUrl: 'inpt.html', // <==== no.
    // template: 'the contents of inpt.html' <==== no.
    link: function(scope, elem, attrs, model) {

       //this is where things vary.

    }
  }

,
,
,

Несколько вещей, которые я пробовал - (plunkr)

предположим, что эта часть постоянна:

function action(a, b, c){ alert(a); alert(b); alert(c); }

app.directive('accounts', ['$compile', function($compile) {
  return {
    require: 'ngModel',
    restrict: 'A',
    scope: {},
    transclude: true,
    link: function(scope, elem, attrs, model) {

       //this is where things vary.

    }
  }
}]);

,
,
,

Каждая итерация следующего (комментирование и т. Д.):

 var a, b, c;
  attrs.ngPattern      = /^\d+$/;
  attrs.ngMinlength    = '3';
  attrs.ngMaxlength    = '10';

  attrs.ngChange = function(){
  a=  Object.keys(model);
  b=  Object.keys(elem);
  c=  Object.keys(attrs);
    action(a, b, c );
  }

  $compile(attrs);
  $compile(elem)      
  $compile(scope)

а также:

   var a, b, c;
      if(model.$invalid){
        elem.addClass('test');
      }

      attrs.$set('ngMinlength', '3')
      attrs.$set('ngMaxlength', '3')
      attrs.$set('ngPattern', /^\d+$/);
      $attrs.$set('ngChange','action()');


      $compile(attrs);
      $compile(elem)      
      $compile(scope)

и попробовал с контроллером

app.controller("CtrlCtrl", ['$scope', '$element','$attrs', '$compile',
function ($scope, $elem, $attrs, $compile) {
  var meta = this, a, b,c;
  this.meta = meta;
  this.ctrlr = meta || {}
  this.ctrlr.modl = "abc";
  $attrs.$set('ngMinlength', '3')
  $attrs.$set('ngMaxlength', '10')
  $attrs.$set('ngPattern', /^\d+$/);

  a=  Object.keys($scope);
  b=  Object.keys($elem);
  c=  Object.keys($attrs);

  $attrs.$set.ngChange = function(){
    action(a, b, c );
  }

  $compile($scope);
  $compile($attrs);
  $compile($elem)      
  $compile($scope)  
  // console.log(a);
  // console.log(b);
  // console.log(c);

  }
]);

Я понятия не имею, почему это сложно. Поначалу документация кажется достаточно подробной, но, боже мой, этого недостаточно, когда вы попадаете в окопы. Я посмотрел каждое видео egghead.io, прочитал очень много вещей... серьезно. Если бы это был другой язык, я бы сейчас этому научил.

1 ответ

Решение

Это должно работать:

app.directive('accounts', ['$compile', function($compile) {
  return {
    require: 'ngModel',
    restrict: 'A',
    transclude: true,
    link: function(scope, elem, attrs, model, transcludeFn) {

        // assume this is all escaped and put together properly as a string 
        var template =    " <input type='text' name='derp_herp' ng-model='ctrlr.goal'
            ng-maxlength='10' ng-minlength='3' ng-required='true'
            ng-pattern='/^\d+$/' ng-focus='ctrlr.action()' ng-blur='ctrlr.validate()'
            ng-change='ctrlr.checkValid()'
            />";

        var e = angular.element(template);
        elem.append(e);
        $compile(e)(scope);

        transcludeFn(scope, function(clone) {
           elem.append(clone);
        });                       

    }
  }
}]);

HTML

<div ng-controller='CtrlCtrl as ctrlr' accounts>  
  <button ng-disabled='ctrlr.isValid()'>Click</button>
</div>

[РЕДАКТИРОВАТЬ]

Если вы хотите динамически добавлять директивы атрибутов, вы можете сделать это из функции компиляции родительского элемента:

app.directive('accounts', [function() {
  return {
    require: 'ngModel',
    restrict: 'A',
    compile: function(elem, attrs, model) {
         var input = elem.find('input');
         input.attr('ng-min-length', 3);
         input.attr('ng-max-length', 3);
         // etc


    }
  }
}]);

HTML

<div ng-controller='CtrlCtrl as ctrlr' accounts>  
   <input />
   <button ng-disabled='ctrlr.isValid()'>Click</button>    
</div>

Это работает, потому что вы изменяете дочерние элементы элемента перед угловой компиляцией. Таким образом, нет необходимости в пользовательском этапе компиляции.

[Редактировать]

Вот действующий план:

http://plnkr.co/edit/aJhmzT

Другие вопросы по тегам