web-dev-qa-db-ja.com

入力フィールドにフォーカスを設定する方法

AngularJSで入力フィールドにフォーカスを設定するための 'Angular way'とは何ですか?

より具体的な要件

  1. Modal が開いたら、このModal内の事前定義済みの<input>にフォーカスを設定します。
  2. <input>が見えるようになるたびに(例えば、あるボタンをクリックすることによって)、それにフォーカスを置きます。

私は最初の要件を達成しようとしましたautofocusで、これはModalが最初に開かれたときだけ、そして特定のブラウザでのみ動作します(例えばFirefoxでは動作しません)。

任意の助けをいただければ幸いです。

738
Misha Moroshko
  1. モーダルが開いたら、このモーダル内の定義済みの<入力>にフォーカスを設定します。

ディレクティブを定義し、それがプロパティ/トリガーを監視するようにして、いつ要素にフォーカスするかを知るようにします。

Name: <input type="text" focus-me="shouldBeOpen">

app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
    return {
        //scope: true,   // optionally create a child scope
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                console.log('value=', value);
                if (value === true) {
                    $timeout(function () {
                        element[0].focus();
                    });
                }
            });
            // to address @blesh's comment, set attribute value to 'false'
            // on blur event:
            element.bind('blur', function () {
                console.log('blur');
                scope.$apply(model.assign(scope, false));
            });
        }
    };
}]);

プランカー

モーダルにレンダリングの時間を与えるために$ timeoutが必要と思われる。

「2」 <入力>が表示されるたびに(たとえば、ボタンをクリックすることによって)、フォーカスを置きます。

上記のようなディレクティブを作成してください。スコーププロパティを監視し、それがtrueになったら(ng-clickハンドラで設定します)、element[0].focus()を実行します。あなたのユースケースに依存して、あなたはこれのために$タイムアウトを必要とするかもしれませんしないかもしれません:

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" ng-model="myInput" focus-me="focusInput"> {{ myInput }}
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    link: function(scope, element, attrs) {
      scope.$watch(attrs.focusMe, function(value) {
        if(value === true) { 
          console.log('value=',value);
          //$timeout(function() {
            element[0].focus();
            scope[attrs.focusMe] = false;
          //});
        }
      });
    }
  };
});

プランカー


Update 7/2013 :私のオリジナルの分離スコープディレクティブを使った後、埋め込まれた入力フィールド(つまり、モーダルの入力フィールド)に問題がある人がいます。新しいスコープ(またはおそらく新しい子スコープ)を持たないディレクティブは、いくらかの痛みを軽減するはずです。そのため、上記では分離スコープを使用しないように回答を更新しました。以下が元の答えです。

分離スコープを使用した1.の元の答え:

Name: <input type="text" focus-me="{{shouldBeOpen}}">

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '@focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === "true") { 
          $timeout(function() {
            element[0].focus(); 
          });
        }
      });
    }
  };
});

プランカー

分離スコープを使用した2.の元の答え:

<button class="btn" ng-click="showForm=true; focusInput=true">show form and
 focus input</button>
<div ng-show="showForm">
  <input type="text" focus-me="focusInput">
  <button class="btn" ng-click="showForm=false">hide form</button>
</div>

app.directive('focusMe', function($timeout) {
  return {
    scope: { trigger: '=focusMe' },
    link: function(scope, element) {
      scope.$watch('trigger', function(value) {
        if(value === true) { 
          //console.log('trigger',value);
          //$timeout(function() {
            element[0].focus();
            scope.trigger = false;
          //});
        }
      });
    }
  };
});

プランカー

ディレクティブでtrigger/focusInputプロパティをリセットする必要があるので、双方向データバインディングには '='が使用されます。最初のディレクティブでは、 '@'で十分です。また、@は常に文字列になるため、 '@'を使用する場合はトリガ値を "true"と比較します。

561
Mark Rajcok

(編集:私はこの説明の下に更新された解決策を追加しました)

マークRajcokは男です...そして彼の答えは正当な答えですが、それは 持っている 欠陥がありました(申し訳ありませんがマーク)...

...ブール値を使用して入力に焦点を合わせ、次に入力をぼかしてから、もう一度入力に焦点を合わせるようにしてみてください。ブール値をfalseにリセットしてから$ digestにリセットしてからtrueにリセットしない限り、機能しません。式で文字列比較を使用している場合でも、文字列を別の$ digestに変更してから元に戻す必要があります。 (これはblurイベントハンドラで解決されました。)

だから私はこの代替解決策を提案する:

イベント、Angularの忘れられた機能を使用してください。

JavaScriptは結局のところイベントが大好きです。イベントは本質的に疎結合であり、さらに優れているのは、あなたの$ダイジェストに別の$ウォッチを追加するのを避けることです。

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on(attr.focusOn, function(e) {
          elem[0].focus();
      });
   };
});

だから今、あなたはこのようにそれを使うことができます:

<input type="text" focus-on="newItemAdded" />

そしてアプリのどこにでも... 

$scope.addNewItem = function () {
    /* stuff here to add a new item... */

    $scope.$broadcast('newItemAdded');
};

あなたがこのような何かでいろいろなことをすることができるので、これは素晴らしいです。一つには、あなたはすでに存在する出来事に結びつくことができます。別のこととして、あなたはあなたのアプリの他の部分が購読できるイベントをあなたのアプリのさまざまな部分が公開することによってスマートなことをし始めます。

とにかく、この種のことは私に "イベント駆動"を叫ぶ。私はAngular開発者として、$ scopeの形をしたペグをイベントの形の穴に打ち込むのは本当に難しいと思います。

それは最善の解決策ですか?私は知らないよ。それは a 解です。


更新されたソリューション

以下の@ ShimonRachlenkoのコメントの後、私はこれを行う方法を少し変更しました。今、私はサービスと "舞台裏"のイベントを処理するディレクティブの組み合わせを使用します。

それ以外は、上記と同じ原則です。

これは簡単なデモPlunkです

使用法

<input type="text" focus-on="focusMe"/>
app.controller('MyCtrl', function($scope, focus) {
    focus('focusMe');
});

ソース

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on('focusOn', function(e, name) {
        if(name === attr.focusOn) {
          elem[0].focus();
        }
      });
   };
});

app.factory('focus', function ($rootScope, $timeout) {
  return function(name) {
    $timeout(function (){
      $rootScope.$broadcast('focusOn', name);
    });
  }
});
258
Ben Lesh

私があなたが本当に必要とするのはこれだけであるとき私は他の答えのいくつかが過度に複雑であるとわかりました

app.directive('autoFocus', function($timeout) {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            $timeout(function(){
                _element[0].focus();
            }, 0);
        }
    };
});

使い方は 

<input name="theInput" auto-focus>

我々はタイムアウトを使用して、それがゼロであっても、DOM内のものをレンダリングさせます - それは少なくともそれを待っています。

234
ecancil

HTMLは属性autofocusを持ちます。

<input type="text" name="fname" autofocus>

http://www.w3schools.com/tags/att_input_autofocus.asp

87
Rayron Victor

Angularに組み込まれているjqlite機能も使用できます。

angular.element('.selector').trigger('focus');

59
JordanC

これはうまく機能し、入力制御に集中するための角度のある方法です。

angular.element('#elementId').focus()

これはタスクを実行するための純粋な角度のある方法ではありませんが、構文は角度のスタイルに従います。 JqueryはAngular(jQLite => JQuery Light)を使用して間接的および直接的にDOMにアクセスします。

必要に応じて、このコードは簡単に簡単なangleディレクティブの中に置くことができ、そこでは要素は直接アクセス可能です。

52
Sanjeev Singh

$ timeoutが要素を創造に集中させる良い方法ではないと思います。これは、角度ドキュメントの曖昧な深さから掘り下げた、組み込みの角度機能を使用する方法です。リンク前とリンク後の機能で、 "link"属性を "pre"と "post"に分割する方法に注目してください。

作業例:http://plnkr.co/edit/Fj59GB

// this is the directive you add to any element you want to highlight after creation
Guest.directive('autoFocus', function() {
    return {
        link: {
            pre: function preLink(scope, element, attr) {
                console.debug('prelink called');
                // this fails since the element hasn't rendered
                //element[0].focus();
            },
            post: function postLink(scope, element, attr) {
                console.debug('postlink called');
                // this succeeds since the element has been rendered
                element[0].focus();
            }
        }
    }
});
<input value="hello" />
<!-- this input automatically gets focus on creation -->
<input value="world" auto-focus />

完全AngularJSディレクティブドキュメント:https://docs.angularjs.org/api/ng/service/$compile

30
Cody Moniz

これが私の最初の解決策です:

プランカー

var app = angular.module('plunker', []);
app.directive('autoFocus', function($timeout) {
    return {
        link: function (scope, element, attrs) {
            attrs.$observe("autoFocus", function(newValue){
                if (newValue === "true")
                    $timeout(function(){element[0].focus()});
            });
        }
    };
});

そしてHTML:

<button ng-click="isVisible = !isVisible">Toggle input</button>
<input ng-show="isVisible" auto-focus="{{ isVisible }}" value="auto-focus on" />

それは何をしますか:

Ng-showで表示されるようになるので、入力に焦点を合わせます。ここでは$ watchや$の使用はありません。

17
Edhowler

最近のモデルと同じように、双方向のバインディングフォーカスディレクティブを書きました。

このようにfocusディレクティブを使うことができます。

<input focus="someFocusVariable">

コントローラのどこかにsomeFocusVariableスコープ変数をtrueにすると、入力がフォーカスされます。そしてもしあなたが入力を「ぼかし」たいのであれば、someFocusVariableをfalseに設定することができます。これはMark Rajcokの最初の答えに似ていますが、双方向のバインディングです。

これが指令です。

function Ctrl($scope) {
  $scope.model = "ahaha"
  $scope.someFocusVariable = true; // If you want to focus initially, set this to true. Else you don't need to define this at all.
}

angular.module('experiement', [])
  .directive('focus', function($timeout, $parse) {
    return {
      restrict: 'A',
      link: function(scope, element, attrs) {
          scope.$watch(attrs.focus, function(newValue, oldValue) {
              if (newValue) { element[0].focus(); }
          });
          element.bind("blur", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=false"); 
              }, 0);
          });
          element.bind("focus", function(e) {
              $timeout(function() {
                  scope.$apply(attrs.focus + "=true");
              }, 0);
          })
      }
    }
  });

使用法:

<div ng-app="experiement">
  <div ng-controller="Ctrl">
    An Input: <input ng-model="model" focus="someFocusVariable">
    <hr>
        <div ng-click="someFocusVariable=true">Focus!</div>  
        <pre>someFocusVariable: {{ someFocusVariable }}</pre>
        <pre>content: {{ model }}</pre>
  </div>
</div>

これはフィドルです:

http://fiddle.jshell.net/ubenzer/9FSL4/8/ /

17
Umut Benzer

BootstrapプラグインでAngularを使う人のために:

http://angular-ui.github.io/bootstrap/#/modal

モーダルインスタンスのopened約束にフックすることができます。

modalInstance.opened.then(function() {
        $timeout(function() {
            angular.element('#title_input').trigger('focus');
        });
    });

modalInstance.result.then(function ( etc...
10
BPH

私は一般的な表現を使うのが便利だと思いました。これにより、入力テキストが有効なときに自動的にフォーカスを移動するなどのことができます

<button type="button" moo-focus-expression="form.phone.$valid">

または、ユーザーが固定長フィールドに入力したときに自動的にフォーカスする

<button type="submit" moo-focus-expression="smsconfirm.length == 6">

そしてもちろんロード後のフォーカス

<input type="text" moo-focus-expression="true">

ディレクティブのコード

.directive('mooFocusExpression', function ($timeout) {
    return {
        restrict: 'A',
        link: {
            post: function postLink(scope, element, attrs) {
                scope.$watch(attrs.mooFocusExpression, function (value) {

                    if (attrs.mooFocusExpression) {
                        if (scope.$eval(attrs.mooFocusExpression)) {
                            $timeout(function () {
                                element[0].focus();
                            }, 100); //need some delay to work with ng-disabled
                        }
                    }
                });
            }
        }
    };
});
7
winry

独自のディレクティブを作成する代わりに、単にJavaScript関数を使用してフォーカスを達成することが可能です。

これが一例です。

Htmlファイルでは:

<input type="text" id="myInputId" />

ファイルのjavascript、たとえばコントローラ内で、フォーカスをアクティブにする場所。

document.getElementById("myInputId").focus();
7
user3657103

ゾンビを復活させたり、自分自身のディレクティブを接続したりしないでください。

https://github.com/hiebj/ng-focus-if

http://plnkr.co/edit/MJS3zRk079Mu72o5A9l6?p=preview

<input focus-if />

(function() {
    'use strict';
    angular
        .module('focus-if', [])
        .directive('focusIf', focusIf);

    function focusIf($timeout) {
        function link($scope, $element, $attrs) {
            var dom = $element[0];
            if ($attrs.focusIf) {
                $scope.$watch($attrs.focusIf, focus);
            } else {
                focus(true);
            }
            function focus(condition) {
                if (condition) {
                    $timeout(function() {
                        dom.focus();
                    }, $scope.$eval($attrs.focusDelay) || 0);
                }
            }
        }
        return {
            restrict: 'A',
            link: link
        };
    }
})();
7
Jon Hieb

最初に、焦点を合わせる公式な方法は 1.1のロードマップ です。その間、あなたは設定フォーカスを実装するためのディレクティブを書くことができます。

次に、アイテムが表示された後でそのアイテムにフォーカスを設定するには、現在回避策が必要です。 $timeoutを使ってelement focus()への呼び出しを遅らせるだけです。

フォーカス、ぼかし、選択についても同じcontroller-modified-DOM問題があるので、ng-targetディレクティブを持つことを提案します。

<input type="text" x-ng-model="form.color" x-ng-target="form.colorTarget">
<button class="btn" x-ng-click="form.colorTarget.focus()">do focus</button>

ここに角のあるスレッド: http://goo.gl/ipsx4 、そしてここにブログが書かれた詳細: http://goo.gl/4rdZa

次のディレクティブは、あなたのng-target属性によって指定されるようにあなたのコントローラの中に.focus()関数を作成します。 (.blur().select()も作成します。)デモ: http://jsfiddle.net/bseib/WUcQX/

6
broc.seib

モーダルでうまく機能する単純なもの:

.directive('focusMeNow', ['$timeout', function ($timeout)
{
    return {
        restrict: 'A',

        link: function (scope, element, attrs)
        {


            $timeout(function ()
            {
                element[0].focus();
            });



        }
    };
}])

<input ng-model="your.value" focus-me-now />
4
Shawn Dotey

あなたがちょうどngクリックによって制御された単純な焦点を望むならば。

HTML:

<input ut-focus="focusTigger">

<button ng-click="focusTrigger=!focusTrigger" ng-init="focusTrigger=false"></button>

指令:

'use strict'

angular.module('focus',['ng'])
.directive('utFocus',function($timeout){
    return {
        link:function(scope,elem,attr){
            var focusTarget = attr['utFocus'];
            scope.$watch(focusTarget,function(value){
                $timeout(function(){
                    elem[0].focus();
                });
            });
        }
    }
});
4
TOBlender

マークとブレスは素晴らしい答えを持っています。しかし、Mark'sはBleshが指摘している(実装が複雑であることに加えて)欠点があり、Bleshの答えには、特にフォーカス要求をフロントエンドに送信することだけに役立つサービスの作成に意味的な誤りがあると思います。すべてのディレクティブがリスニングするまでイベントを遅らせます。

それで、ここで私がやったことはBleshの答えから多くを盗むが、コントローラーイベントと "ロード後"サービスのセマンティクスを別々にしておくことです。

これにより、コントローラーイベントを特定の要素にフォーカスする以外のことに簡単にフックでき、必要な場合にのみ "ロード後"機能のオーバーヘッドを招くことができます。

使用法

<input type="text" focus-on="controllerEvent"/>
app.controller('MyCtrl', function($scope, afterLoad) {
  function notifyControllerEvent() {
      $scope.$broadcast('controllerEvent');
  }

  afterLoad(notifyControllerEvent);
});

ソース

app.directive('focusOn', function() {
   return function(scope, elem, attr) {
      scope.$on(attr.focusOn, function(e, name) {
        elem[0].focus();
      });
   };
});

app.factory('afterLoad', function ($rootScope, $timeout) {
  return function(func) {
    $timeout(func);
  }
});
3
joshperry

これはngModelControllerを使うことも可能です。 1.6以降での作業(古いバージョンでは知らない)。

_ html _

<form name="myForm">
    <input type="text" name="myText" ng-model="myText">
</form>

_ js _

$scope.myForm.myText.$$element.focus();

-

N.B .:状況によっては、タイムアウト関数でラップする必要があるかもしれません。

N.B.²:controllerAsを使うとき、これはほとんど同じです。 name="myForm"name="vm.myForm"に、そしてJSではvm.myForm.myText.$$element.focus();に置き換えてください。

3

PostLinkingの装飾された要素に焦点を合わせるように指示するディレクティブを作成することができます。 

angular.module('directives')
.directive('autoFocus', function() {
    return {
        restrict: 'AC',
        link: function(_scope, _element) {
            _element[0].focus();
        }
    };
});

それから、あなたのhtmlに:

<input type="text" name="first" auto-focus/> <!-- this will get the focus -->
<input type="text" name="second"/>

PostLinkingはHTML処理でのみ行われるため、これはng-showではなく、modalsおよびng-if要素の切り替えに有効です。

3
ibaixas

おそらく、ES6時代の最も簡単な解決策です。

次のライナーディレクティブを追加すると、Angular.jsに対してHTMLの「autofocus」属性が有効になります。

.directive('autofocus', ($timeout) => ({link: (_, e) => $timeout(() => e[0].focus())}))

今、あなたはちょうどHTML5のオートフォーカス構文を使うことができます:

<input type="text" autofocus>
3
Tsuneo Yoshioka

次の命令は私のためにトリックをしました。入力に同じautofocus html属性を使用してください。

.directive('autofocus', [function () {
    return {
        require : 'ngModel',
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.focus();
        }
    };
}])
2
Kishore Relangi

初心者ですが、 ui.bootstrap.modal でこのディレクティブを使用することはできませんでした。

directives.directive('focus', function($timeout) {
    return {
        link : function(scope, element) {
            scope.$watch('idToFocus', function(value) {
                if (value === element[0].id) {
                    $timeout(function() {
                        element[0].focus();
                    });
                }
            });
        }
    };
});

そして$ modal.openメソッドでは、フォーカスを置くべき要素を示すために次のように使用しました。

var d = $modal.open({
        controller : function($scope, $modalInstance) {
            ...
            $scope.idToFocus = "cancelaAteste";
    }
        ...
    });

テンプレート上で私はこれを持っています:

<input id="myInputId" focus />
2
pitervergara

ModalInstanceを使用していてオブジェクトがある場合は、モーダルを開いた後に「then」を使用してアクションを実行できます。 modalInstanceを使用しておらず、モーダルを開くようにハードコードされている場合は、イベントを使用できます。 $タイムアウトは良い解決策ではありません。

あなたはすることができます(Bootstrap3):

$("#" + modalId).on("shown.bs.modal", function() {
    angular.element("[name='name']").focus();
});

ModalInstanceでは、open modalの後にどのようにコードを実行するかについてlibraryを調べることができます。

このように$ timeoutを使用しないでください。$ timeoutは0、1、10、30、50、200、またはそれ以上になる可能性があります。これはクライアントコンピュータおよびモーダルを開くプロセスによって異なります。

$ timeoutを使用しないでください。あなたがフォーカスできるときにメソッドに知らせます;)

私はこれが役立つことを願っています! :)

2

Mark RajcokのfocusMeディレクティブを編集して、1つの要素で複数のフォーカスに対応します。

HTML:

<input  focus-me="myInputFocus"  type="text">

angularJsコントローラの場合:

$scope.myInputFocus= true;

AngulaJS指令:

app.directive('focusMe', function ($timeout, $parse) {
    return {
        link: function (scope, element, attrs) {
            var model = $parse(attrs.focusMe);
            scope.$watch(model, function (value) {
                if (value === true) {
                    $timeout(function () {
                        scope.$apply(model.assign(scope, false));
                        element[0].focus();
                    }, 30);
                }
            });
        }
    };
});
2
Mohamad Khani

目的のフォーカス要素がディレクティブテンプレートに挿入されている場合、前の回答はすべて機能しません。次のディレクティブは、単純な要素またはディレクティブを挿入した要素の両方に適合します(TypeScriptで記述しました)。内部のフォーカス可能な要素のセレクターを受け入れます。自己要素に焦点を合わせる必要がある場合-セレクターパラメーターをディレクティブに送信しないでください:

module APP.Directives {

export class FocusOnLoadDirective implements ng.IDirective {
    priority = 0;
    restrict = 'A';

    constructor(private $interval:any, private $timeout:any) {

    }

    link = (scope:ng.IScope, element:JQuery, attrs:any) => {
        var _self = this;
        var intervalId:number = 0;


        var clearInterval = function () {
            if (intervalId != 0) {
                _self.$interval.cancel(intervalId);
                intervalId = 0;
            }
        };

        _self.$timeout(function(){

                intervalId = _self.$interval(function () {
                    let focusableElement = null;
                    if (attrs.focusOnLoad != '') {
                        focusableElement = element.find(attrs.focusOnLoad);
                    }
                    else {
                        focusableElement = element;
                    }
                    console.debug('focusOnLoad directive: trying to focus');
                    focusableElement.focus();
                    if (document.activeElement === focusableElement[0]) {
                        clearInterval();
                    }
                }, 100);

                scope.$on('$destroy', function () {
                    // Make sure that the interval is destroyed too
                    clearInterval();
                });

        });
    };

    public static factory = ():ng.IDirectiveFactory => {
        let directive = ($interval:any, $timeout:any) => new FocusOnLoadDirective($interval, $timeout);
        directive.$inject = ['$interval', '$timeout'];
        return directive;
    };
}

angular.module('common').directive('focusOnLoad', FocusOnLoadDirective.factory());

}

単純な要素の使用例:

<button tabindex="0" focus-on-load />

内部要素の使用例(通常、テンプレートを使用したディレクティブのような動的に挿入された要素の場合):

<my-directive focus-on-load="input" />

「入力」の代わりに任意のjQueryセレクターを使用できます

2
Ofir Meguri

特定の要素に焦点を合わせたい場合は、以下の方法を使用できます。

  1. focusというサービスを作成します。

    angular.module('application')
    .factory('focus', function ($timeout, $window) {
        return function (id) {
            $timeout(function () {
                var element = $window.document.getElementById(id);
                if (element)
                    element.focus();
            });
        };
    });
    
  2. 電話をかけたい場所からコントローラーに注入してください。

  3. このサービスに電話してください。

1
Rakesh Burbure

私はより良い解決策を探し、それを見つけるのではなく、代わりにそれを作成しなければならない後にこの議論に貢献したいと思います。

基準: 1。再利用性を高めるために、解決策は親コントローラの範囲とは無関係であるべきである[2]。いくつかの状態を監視するために$ watchを使用するのは避けてください、これは両方とも遅く、ダイジェストループのサイズを増大させ、テストをより困難にします。ダイジェストループを引き起こすために$ timeoutや$ scope。$ apply()を使用しないでください。指令が開いて使用されている要素内に入力要素があります。

これは私が一番好きだった解決策です:

指令: 

.directive('focusInput', [ function () {
    return {
        scope: {},
        restrict: 'A',
        compile: function(elem, attr) {
            elem.bind('click', function() {
                elem.find('input').focus();                
            });
        }        
    };
}]);

HTML: 

 <div focus-input>
     <input/>
 </div>

これが誰かに役立つことを願っています!

1
xiaoma

簡単です..これを試してください

html

<select id="ddl00">  
 <option>"test 01"</option>  
</select>

ジャバスクリプト

document.getElementById("ddl00").focus();
1

あなたはそれに焦点を当てるためにHTML入力でブール値を取得する以下のディレクティブを使用することができます...

//js file
angular.module("appName").directive("ngFocus", function () {
       return function (scope, elem, attrs, ctrl) {
             if (attrs.ngFocus === "true") {
                 $(elem).focus();
             }
             if (!ctrl) {
                 return;
             }
       elem.on("focus", function () {
            elem.addClass("has-focus");
            scope.$apply(function () {
                ctrl.hasFocus = true;
            });
        });
    };
});

<!-- html file -->
<input type="text" ng-focus="boolValue" />

以下のコードに注意して、コントローラの関数をngFocusディレクティブ値に設定することもできます。

<!-- html file -->
<input type="text" ng-focus="myFunc()" />


//controller file
$scope.myFunc=function(){
      if(condition){
          return true;
      }else{
          return false;
      }
}

このディレクティブは、HTMLページをレンダリングするときに発生します。 

0
user7339584

指令は不要だと思います。 HTMLのid属性とclass属性を使用して必要な要素を選択し、サービスにdocument.getElementByIdまたはdocument.querySelectorを使用してフォーカス(または同等のjQuery)を適用させます。

マークアップは標準のHTML/Angularディレクティブで、選択用のID /クラスが追加されています

<input id="myInput" type="text" ng-model="myInputModel" />

コントローラーがイベントをブロードキャストする

$scope.$emit('ui:focus', '#myInput');

UIサービスではquerySelectorを使用します - 複数の一致がある場合(クラスによるなど)、最初のものだけを返します。

$rootScope.$on('ui:focus', function($event, selector){
  var elem = document.querySelector(selector);
  if (elem) {
    elem.focus();
  }
});

あなたはダイジェストサイクルを強制するために$ timeout()を使いたいかもしれません。

0
johans

タイムアウトに頼ることが賢明かどうかはわかりませんが、このコードはAngularsがDOMを更新した後に実行されるため、ng-repeatには有効です。したがって、すべてのオブジェクトが存在することを確認してください。

myApp.directive('onLastRepeat', [function () {
        return function (scope, element, attrs) {
            if (scope.$last) setTimeout(function () {
                scope.$emit('onRepeatLast', element, attrs);
            }, 1);
        };
    }]);
    //controller for grid
    myApp.controller('SimpleController', ['$scope', '$timeout', '$http', function ($scope, $timeout, $http)
    {
        var newItemRemoved = false;
        var requiredAlert = false;
        //this event fires up when angular updates the dom for the last item
        //it's observed, so here, we stop the progress bar
        $scope.$on('onRepeatLast', function (scope, element, attrs) {
            //$scope.complete();
            console.log('done done!');
            $("#txtFirstName").focus();
        });
    }]);
0
Alex

プログラムで要素に対する任意のアクションを呼び出す:click()、focus()、select()...

使用法:

<a href="google.com" auto-action="{'click': $scope.autoclick, 'focus': $scope.autofocus}">Link</a>

指令:

/**
 * Programatically Triggers given function on the element
 * Syntax: the same as for ng-class="object"
 * Example: <a href="google.com" auto-action="{'click': autoclick_boolean, 'focus': autofocus_boolean}">Link</a>
 */
app.directive('focusMe', function ($timeout) {
    return {
        restrict: 'A',
        scope: {
            autoAction: '<',
        },
        link: function (scope, element, attr) {
            const _el = element[0];
            for (const func in scope.autoAction) {
                if (!scope.autoAction.hasOwnProperty(func)) {
                    continue;
                }
                scope.$watch(`autoAction['${func}']`, (newVal, oldVal) => {
                    if (newVal !== oldVal) {
                        $timeout(() => {
                            _el[func]();
                        });
                    }
                });
            }

        }
    }
});

この問題に対処するには、初期化時に(できれば)コントローラ内で、またはng-initとして変数を設定します。

 <input ng-init="autofocus=true" auto-action="{'focus': autofocus}">
0
Mesco

コーヒーを入れるだけです。

app.directive 'ngAltFocus', ->
    restrict: 'A'
    scope: ngAltFocus: '='
    link: (scope, el, attrs) ->
        scope.$watch 'ngAltFocus', (nv) -> el[0].focus() if nv
0