16

例如,我想创建一个类似于 AngularJS 实现“电子邮件”的方式的自定义输入类型。

<input type="email" ng-model="user.email" />

我想创建的是这样的输入类型:

<input type="path" ng-model="page.path" />

关于如何实现这一点的任何想法?到目前为止,我只能弄清楚如何实现自定义指令,其中“路径”是标签、属性或类的名称。

例如,我可以让它工作,但它与其他表单字段不一致,我真的希望它们看起来一样。

<input type="text" ng-model="page.path" path />
app.directive('path', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) { ... }
  };
});
4

3 回答 3

18

如果 type 属性设置为“path”,您可以通过使用自定义逻辑创建输入指令来创建自己的输入 type="path"。

我创建了一个简单的示例,只需替换\/. 该指令如下所示:

module.directive('input', function() {
    return {
        restrict: 'E',
        require: 'ngModel',
        link: function (scope, element, attr, ngModel) {
          if (attr.type !== 'path') return;

          // Override the input event and add custom 'path' logic
          element.unbind('input');
          element.bind('input', function () {
            var path = this.value.replace(/\\/g, '/');

            scope.$apply(function () {
              ngModel.$setViewValue(path);
            });
          });
        }
    };
});

Example

更新:将 , 更改为 ,以on删除jQuery 依赖项。示例已更新。offbindunbind

于 2013-02-06T19:33:20.747 回答
2

可以通过使用ngModelController$parsers的属性来实现替代解决方案。此属性表示在将输入组件的值传递给验证(并最终将它们分配给模型)之前应用于输入组件值的解析器链。有了这个,解决方案可以写成:

module.directive('input', function() {
    return {
        restrict: 'E',
        require: 'ngModel',
        link: function (scope, element, attr, ngModel) {
          if (attr.type !== 'path') return;

          ngModel.$parsers.push(function(v) {
            return v.replace(/\\/g, '/');
          });
        }
    };
});

请注意,还有另一个属性$formatters是格式化程序的管道,可将模型值转换为输入中显示的值。

请参阅此处了解 plunker。

于 2015-08-17T14:20:16.750 回答
0

考虑到 compile 函数是第一个行,它会不会更好:

module.directive('input', function() {
  return {
    restrict: 'E',
    require: 'ngModel',
    compile: function Compile(tElement, tAttrs) {
      if (tAttrs.type !== 'path') return;

      return function PostLink(scope, element, attr, ngModel) {
        // Override the input event and add custom 'path' logic
        element.unbind('input');
        element.bind('input', function () {
          var path = this.value.replace(/\\/g, '/');

          scope.$apply(function () {
            ngModel.$setViewValue(path);
          });
        });
      }
    }
  };
});
于 2016-08-24T14:36:00.043 回答