web-dev-qa-db-ja.com

カスタム入力タイプを作成するにはどうすればよいですか?

たとえば、AngularJSが「email」を実装するのと同様のカスタム入力タイプを作成したいと思います。

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

私が作成したいのは、次のような入力タイプです。

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

これをどのように達成できるかについてのアイデアはありますか?これまでのところ、「path」がタグ、属性、またはクラスの名前であるカスタムディレクティブを実装する方法を理解することしかできませんでした。

たとえば、これを機能させることはできますが、他のフォームフィールドでは一貫性がないであり、実際には同じように見せたいと思います。

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

Type属性が "path"に設定されている場合は、カスタムロジックを使用してinputディレクティブを作成することにより、独自のinput 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

Updateonoffbindunbindに変更して削除jQueryの依存関係。例が更新されました。

18
Martin

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があることに注意してください。

プランカーについては ここ を参照してください。

2
widmoser

コンパイル関数が最初の行であることを考えると、次の場合は良くないでしょうか。

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);
          });
        });
      }
    }
  };
});
0
Chris2402