10

テストケース: http: //jsbin.com/ahugeg/4/edit(少し長い)

ng-repeat上記のテストケースでは、ディレクティブによって生成された3つの入力要素があります。このテストケースでの私の意図は、これらの入力の1つで上向き/下向き矢印を押すと、その方向で使用可能な入力がある場合、対応する方向の入力にフォーカスが移動するはずです。

私はAngularJSを初めて使用するため、これを行うための簡単な方法が見当たらない可能性があります。とにかく、私は2つの新しいディレクティブ(on-upと)を定義して、upイベントとdownイベントを処理し、フォーカスが移動する相対的な正しいエントリを渡して、 andメソッドon-downを呼び出しています。これは私が立ち往生しているところです。$scope.focusNext$scope.focusPrev

コントローラーでDOM要素を処理するのは角度のある方法ではないことは知っていますが、フォーカスがモデルの属性/プロパティとしてどのように見えるかはわかりません。別のものを用意することも考えましたが、そのプロパティの変更を監視$scope.focusedEntryする必要がありますか?変更を検出して変更を検出した場合でも、フォーカスしたいエントリに対応する入力要素にアクセスするにはどうすればよいですか?

これをどのように行うべきかについての助けは非常にありがたいです。

4

3 に答える 3

16

私はこれを書き上げて簡単にテストしました-コントローラーとHTMLに余分な混乱を与えることなく、必要なことを実行します。ここで動作するのを見てください。

HTML:

<body ng-controller="Ctrl">
    <input ng-repeat="entry in entries" value="{{entry}}" key-focus />
</body>

コントローラ:

function Ctrl($scope) {
  $scope.entries = [ 'apple', 'ball', 'cow' ];
}

指令:

app.directive('keyFocus', function() {
  return {
    restrict: 'A',
    link: function(scope, elem, attrs) {
      elem.bind('keyup', function (e) {
        // up arrow
        if (e.keyCode == 38) {
          if(!scope.$first) {
            elem[0].previousElementSibling.focus();
          }
        }
        // down arrow
        else if (e.keyCode == 40) {
          if(!scope.$last) {
            elem[0].nextElementSibling.focus();
          }
        }
      });
    }
  };
});
于 2013-02-09T00:35:55.163 に答える
6

私も同様の問題を抱えており、この単純なディレクティブを使用しました。属性がtrueとして解決される場合、フォーカスがある場合にのみng-showおよびng-hideとして機能します。

.directive('focusOn',function() {
    return {
        restrict : 'A', 
        link : function($scope,$element,$attr) {
            $scope.$watch($attr.focusOn,function(focusVal) {
                if(focusVal === true) {
                    setTimeout(function() {
                        $element.focus();
                    },50);
                }
            });
        }
    }
})
于 2013-02-08T23:49:01.093 に答える
4

@Trevorのソリューションに触発されて、これが私が決めたものです、

app.directive('focusIter', function () {

    return function (scope, elem, attrs) {
        var atomSelector = attrs.focusIter;

        elem.on('keyup', atomSelector, function (e) {
            var atoms = elem.find(atomSelector),
                toAtom = null;

            for (var i = atoms.length - 1; i >= 0; i--) {
                if (atoms[i] === e.target) {
                    if (e.keyCode === 38) {
                        toAtom = atoms[i - 1];
                    } else if (e.keyCode === 40) {
                        toAtom = atoms[i + 1];
                    }
                    break;
                }
            }

            if (toAtom) toAtom.focus();

        });

        elem.on('keydown', atomSelector, function (e) {
            if (e.keyCode === 38 || e.keyCode === 40)
                e.preventDefault();
        });

    };
});

focus-iterこれは、繰り返されるすべての入力の親要素に設定される属性を定義します。ここで実際の動作を参照してください:http://jsbin.com/ahugeg/10/

@Trevorの利点は、focus-iter属性の値に任意のセレクターを設定して、フォーカスジャンプが機能する要素を正確に指定できることです。クレイジーな例として、focus-iter属性をinput:even:)に設定してみてください。input私のアプリケーションでは、テストケースとは異なり、sの周りにかなりの追加のマークアップが付いているので、これは役立ちます。

于 2013-02-09T05:45:57.193 に答える