0

我正在创建一个smart input指令,它将包装一个文本输入元素,它需要访问输入元素上的模型才能操作指令上的某些类。

因为输入元素可以是多种类型之一(文本、电子邮件、密码),所以我需要嵌入指令并能够为每种类型添加不同类型的验证。

我遇到的问题(与 Internet 上的许多其他问题一样)是范围继承。

这是我当前的代码看起来像
HTML

<smart-input ng-model="username">
  <span ng-show="isTyping">{{ placeholder }}</span>
  <input type="text" name="username" ng-model="username" ng-minlength="4" ng-maxlength="20" required />
</smart-input>

JS

angular.module('myApp').directive('smartInput', function ($compile) {
  return {
    restrict: 'E',
    transclude: true,
    replace: true,
    scope: {
      model: '=ngModel'
    },
    template: '<div class="text-input" ng-class="{typing: isTyping}" ng-transclude>' +
              '</div>',
    link: function(scope, element, attrs) {
      scope.isTyping = false;

      scope.$watch('model', function(value) {
        console.log(value);
        scope.isTyping = value.length > 0;
      });
    }
  };
});

基本上,value$watch 函数内部是未定义的,所以很明显我没有正确执行此操作。

那么,如何将模型绑定到输入字段,同时让指令具有对同一对象的引用并能够获得watch它的值?

4

1 回答 1

0

当您将隔离范围与包含一起使用时,您的范围没有父/子关系。它看起来像这样:

<controllerScope>
     <smartInputScope>
     <transcludedContentScope>

这就是为什么为了访问 smartInputScope 的model属性,我们必须访问$$prevSibling.model在您的第一个示例ng-model="username"中,因为此范围继承自 controllerScope,它正在访问父范围的属性。

查看我的自定义嵌入解决方案:http://plnkr.co/edit/cV9urKJdcn4mKlpqPJTr? p =preview

app.directive('smartInput', function($compile) {
  return {
    restrict: 'E',
    transclude: true,
    replace: true,
    scope: {
      model: '=ngModel'
    },
    template: '<div class="text-input" ng-class="{typing: isTyping}">' +
      '</div>',
    compile: function(element, attr, linker) {
      return {
        pre: function(scope, element, attr) {
          linker(scope, function(clone) { //bind the scope your self
            element.append(clone); // add to DOM
          });
        },
        post: function postLink(scope, iElement, iAttrs) {
          scope.isTyping = false;

          scope.$watch('model', function(value) {
            console.log(value);
            scope.isTyping = value.length > 0;
          });
        }
      };
    }
  };
});

在 html 中,我不再需要$$prevSibling

<input type="text" name="username" ng-model="model" ng-minlength="4" ng-maxlength="20" required />
于 2014-02-04T03:03:59.990 回答