微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – 将自定义指令添加到已具有角度指令的现有输入[ng-model / ng-required]

我想使用一个用ng-model和ng-required修饰的标准输入控件,然后添加我自己的自定义属性指令,为控件提供uib-typeahead功能.

我用这个链接让我的指令部分工作.

Add directives from directive in AngularJS

PLUNKR – The Version 2 of the directive does not work correctly with ng-model

我的指令确实添加了typeahead功能并且运行良好,但是在选择项目后它不会将模型绑定到控件上.

我有两个版本的指令.

版本1:是一个元素样式指令,我已经成功使用了一段时间,但是当我不想对输入元素进行更多控制时,它就失败了,特别是当我想使用ng-required =’时true’和其他ng-message指令.

版本2:是一个属性样式指令,我接受了这个,因为我觉得最好只添加我想要的任何标准HTML的typeahead功能,可以选择使用ng-required =’true’,ng-model等. .

虽然这个指令主要起作用,但是它与ng-model没有正确交互,我不知道如何让它工作

angular.module(APP)

.directive('wkLocationSuggest',['$compile',function ($compile) {
  return {
    restrict: 'A',require: 'ngModel',replace: false,//terminal: true,//priority: 0,scope: {
      wkApiModel: '=' // Provide access to the internal data that is returned via the API lookup
    },controller: 'LocationSuggestController',link: function (scope,element,attrs,ngModelCtrl) {
      if (!ngModelCtrl) {
        return;
      }

      element.attr('typeahead','location as row.location for row in typeAhead($viewValue)');
      element.attr('typeahead-wait-ms','750');
      element.attr('typeahead-on-select','onSelectInternal($item,$model,$label)');
      element.attr('typeahead-min-length','2');
      element.attr('typeahead-focus-first','true');

      element.removeAttr("wk-location-suggest");        //remove the location-suggest to avoid indefinite loop
      element.removeAttr("data-wk-location-suggest");   //also remove the same attribute with data- prefix if it exists

      // None of this is working
      //// invoked when model changes from the outside
      //ngModelCtrl.$render = function () {
      //  //scope.innerModel = ngModelCtrl.$modelValue;
      //};

      ////// invoked when model changes from the inside
      //scope.onChange = function (value) {
      //  ngModelCtrl.$setViewValue(scope.innerModel);
      //};

      scope.onSelectInternal = function ($item,$label) {

        // This fires,but it effects the ng-model on the first input,// but not the input that this directive is attached too
        ngModelCtrl.$setViewValue($item.location);

      };

      $compile(element)(scope);

    }
  };
}]);

这两个图像展示了部分问题,可能更好地使用上面的PLUNKR来测试自己

解决方法

我最初试图通过结合ngModel的$setValidity方法在input元素上实现blur来动态地将验证器添加到你的wk-location-suggest-new指令中;但不知道究竟是什么阻止了事件的发射.

因此,我转向另一个指令wk-location-suggest-old并稍微调整一下以适应两种期望的行为.

There,I noticed that you were missing a couple of things:

  • First of all,in order for a form element to glue with the form itself (wkProfileCompany in your case),and to work with ng-model,the element (in the directive template) needs a name.
  • Secondly,ng-required (or required) would work with the form only if it is added as an attribute to the element in the directive template,not the directive which compiles to the template containing the element.

指令定义

您可能已经注意到,我已经将外部作用域中的两个属性传递给指令的内部作用域,即:

>输入元素的名称,
>和一个isrequired标志,用于指定是否需要输入.

.

.directive('wkLocationSuggestOld',[function () {
  return {
    restrict: 'E',require: '?ngModel',scope: {
      name: '@',// <==
      isrequired: '=' // <==
    },template: '<input name="{{name}}" type="text" class="{{innerClass}}" ng-model="innerModel"'
       + ' ng-change="onChange()" uib-typeahead="location as row.location for row in typeAhead($viewValue)" '
       + ' typeahead-wait-ms="750" typeahead-on-select="onSelectInternal($item,$label)" '
       + ' typeahead-min-length="2" typeahead-focus-first="true" '
       + ' ng-required="isrequired">',// <== added ng-required here
    controller: 'LocationSuggestController',ngModel) {
      if (!ngModel) {
          return;
      }          
      ...
}])

HTML

最后,您可以在HTML中使用tweaked指令:

<wk-location-suggest-old class="form-control" type="text" name="location2" ng-model="location2" is-required="true"></wk-location-suggest-old>

Plunker

更新

ng-model没有在wk-location-suggest-new指令中正确绑定到提供的值(即location3)的一个可能原因是你要用一个新的自定义DOM元素替换整个DOM元素,该元素是用指令本身的孤立范围.

由于指令wk-location-suggest-new具有隔离范围,因此范围完全不知道location3,因为location3(以及所有其他位置值)是在MainCtrl的范围内定义的,而不是指令本身的范围;因此,您最终会将输入值绑定到未定义的属性.

link: function (scope,ngModelCtrl) {
   if (!ngModelCtrl) {
     return;
   }
 ...
$compile(element)(scope); // <== here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐