Angular (v1) 指令屏蔽(从显示,而不是模型)输入文本字段中的任何随机子字符串

Angular (v1) directive to mask (from display, not model) any random substring in an input text field

Objective:能够 hide/mask 文本输入字段的子字符串,而不影响 ng-model 变量

示例:

<input type="text" placeholder="enter URL" ng-model="input.url" mask="dilbert">

如果用户输入 admin:dilbert@mylocation.host.com 然后显示显示 admin:*******@mylocation.host.com 而 $scope.input.url 将包含 admin:dilbert@mylocation.host.com

这可能吗?我有一种情况,我只需要在显示表单时将密码隐藏在 URLs 中,如果用户输入它的话。解决方法是保留一个显示变量和一个克隆的实际变量,但这并不是一个真正优雅的解决方案。

进一步解释动机(以解决下面 WilliamB 的评论)

此要求适用于需要配置 URL 的移动应用程序。如果用户已将后端服务器配置为使用基本身份验证(此移动应用程序的每个用户都使用自己的服务器),则 URL 可能 包含基本身份验证凭据

这是一个示例屏幕截图:

a) 当显示URL字段,但未被编辑时,密码被屏蔽,不影响模型变量

b) 为简单起见,在编辑 URL 字段时,密码显示为常规文本(焦点)

c) mask='string' 问题是一种简化。实际上,这个用例可能是一个 mask 指令,如果附加到输入文本字段,则会在输入格式为 url://user:password@domain/path

时屏蔽密码文本

我意识到这只是一个基本的掩码 - 但它是一个移动应用程序,很少有人会开始剖析 DOM 来查看被掩码的内容

ngModel 的控制器提供了为 DOM 设置视图值的能力。像这样:

.directive('mask', function () {
  return {
    require: 'ngModel',
    link: function (scope, elem, attrs, ngModelCtrl) {
      scope.$watch(attrs.ngModel, function (newVal, oldVal) {
        var mask = attrs.mask.replace(/./g, function () { return '*' });
        ngModelCtrl.$viewValue = newVal.replace(attrs.mask, mask);
        ngModelCtrl.$render();
      });
    }
  }
});

这里有一个例子 fiddle: https://jsfiddle.net/7kLb38ys/1/

最终解决方案完全符合我的要求:(不包括通用掩码,但如果需要可以轻松修改 - 我真正需要的是隐藏 URI 的 user:password 字段)

//credit: 
.directive('hidepassword', function () {

  var modelSet = function (str)
  {

        return str;
  };

  var viewSet = function (str)
  {
        //URI.js: https://github.com/garycourt/uri-js
        if (!str) return str;
        var c = URI.parse(str);
        if (c.userinfo) c.userinfo="***:***";
        var vc = URI.serialize({scheme : c.scheme, 
                                userinfo: c.userinfo,
                                host: c.host,
                                port: c.port,
                                path: c.path,
                                query: c.query,
                                fragment: c.fragment
                                });
        console.log ("CONVERTED IS "+vc);


        return vc;
  };

  return {

    restrict: 'A',
      require: 'ngModel',
      link: function (scope, element, attr, ngModel) {
        ngModel.$parsers.push(modelSet);
        ngModel.$formatters.push(viewSet);

        element.bind('blur', function() {
          element.val(viewSet(ngModel.$modelValue));
        });
        element.bind('focus', function () {
          element.val(ngModel.$modelValue);
        });

      }
  };
})