1. ホーム
  2. angularjs

[解決済み] 要素のフォーカスを角度を変えて設定する

2022-09-28 20:59:37

質問

angularでフォーカス要素を設定する方法の例を見た後、それらのほとんどは、フォーカスを設定するために監視するためにいくつかの変数を使用し、それらのほとんどは、フォーカスを設定したい各フィールドに1つの異なる変数を使用していることがわかりました。多くのフィールドを持つフォームでは、多くの異なる変数に意味します。

jqueryの方法を念頭に置いて、しかしangularの方法でそれをしたい、私たちは要素のidを使用して任意の関数でフォーカスを設定するソリューションを作りました、私はangularの非常に新しいので、私はその方法が正しいかどうかいくつかの意見を得たいと思います、問題がある、何でも、私はangularでこれを行うより良い方法を助けることができるもの。

基本的に、私はディレクティブでユーザーによって定義されたスコープの値、またはデフォルトのfocusElementを見て、その値が要素のidと同じであるとき、その要素が自分自身にフォーカスを設定するディレクティブを作成します。

angular.module('appnamehere')
  .directive('myFocus', function () {
    return {
      restrict: 'A',
      link: function postLink(scope, element, attrs) {
        if (attrs.myFocus == "") {
          attrs.myFocus = "focusElement";
        }
        scope.$watch(attrs.myFocus, function(value) {
          if(value == attrs.id) {
            element[0].focus();
          }
        });
        element.on("blur", function() {
          scope[attrs.myFocus] = "";
          scope.$apply();
        })        
      }
    };
  });

何らかの理由でフォーカスを得る必要がある入力は、このようにします。

<input my-focus id="input1" type="text" />

ここで任意の要素にフォーカスを設定する。

<a href="" ng-click="clickButton()" >Set focus</a>

そして、フォーカスを設定する関数の例です。

$scope.clickButton = function() {
    $scope.focusElement = "input1";
}

それはangularの良い解決策ですか?それは私の貧しい経験で私がまだ見ていない問題を持っていますか?

どのように解決するのですか?

あなたの解決方法の問題点は、新しいスコープを作成する他のディレクティブと結びついたときにうまく動作しないことです。例えば ng-repeat . より良い解決策は、コントローラ内で命令的に要素をフォーカスしたり、html内で宣言的に要素をフォーカスできるようなサービス関数を作成することでしょう。

デモ

JAVASCRIPT

サービス

 .factory('focus', function($timeout, $window) {
    return function(id) {
      // timeout makes sure that it is invoked after any other event has been triggered.
      // e.g. click events that need to run before the focus or
      // inputs elements that are in a disabled state but are enabled when those events
      // are triggered.
      $timeout(function() {
        var element = $window.document.getElementById(id);
        if(element)
          element.focus();
      });
    };
  });

ディレクティブ

  .directive('eventFocus', function(focus) {
    return function(scope, elem, attr) {
      elem.on(attr.eventFocus, function() {
        focus(attr.eventFocusId);
      });

      // Removes bound events in the element itself
      // when the scope is destroyed
      scope.$on('$destroy', function() {
        elem.off(attr.eventFocus);
      });
    };
  });

コントローラ

.controller('Ctrl', function($scope, focus) {
    $scope.doSomething = function() {
      // do something awesome
      focus('email');
    };
  });

HTML

<input type="email" id="email" class="form-control">
<button event-focus="click" event-focus-id="email">Declarative Focus</button>
<button ng-click="doSomething()">Imperative Focus</button>