3

我正在向keyup嵌套在 ng-repeats 中的输入添加绑定,以便顺利地从下一个输入到上一个输入,类似于这个问题。不同之处在于解决方案是针对直接相邻的兄弟姐妹的输入。

这是我的 html 的原型:

<div ng-repeat="student in students" >
  <div class="input-append">
    <input class="span3" type="text" ng-model="student.name"
       ng-required="student.name.split(' ').length>1" focus-others index="{{ $index }}" focus="{{ focus.value }}"/>
    <button class="btn btn-danger" type="button" ng-click="deleteInput($index)">X</button>
  </div>
</div>

我目前有两个都可以工作的解决方案。


第一个解决方案- 遍历 dom 寻找输入,匹配关注的输入,然后keyup关注下一个输入:

app.directive('focusOthers', function($timeout){
  return function(scope, element){
    var inputs;
    $timeout(function(){
        inputs = document.querySelectorAll('input[type="text"]');
    },0)
    element.bind('keyup', function(e){
        var current = document.activeElement;      
        if (e.keyCode == 13){
            event.preventDefault();
            var i = 0;
            while( i<inputs.length){
                if (inputs[i]==current){                        
                    var nextInput = inputs[i+1];
                    nextInput.focus();
                    i=inputs.length;
                }
                i++;
            }
        }
    })
}
});

这是一个工作的笨蛋


第二个解决方案- 这是一个更“角度”的解决方案,因为指令处理元素属性内的信息以确定哪个元素获得焦点。

app.directive('focusOthers', function(){
return {
    link: function(scope, element, attrs){
        // scope.index = attrs.index - wouldn't it be nice if this worked?
        attrs.$observe('index', function(val){
            scope.index = parseInt(val);
        });
        attrs.$observe('focus', function(val){
            if(scope.focus.value == scope.index){
                element[0].focus();
            }
        });

        element.bind('keyup', function(e){
            if(e.keyCode==13){
                scope.focus.value = scope.index + 1;
                scope.$apply();
            }
        });
    }
}
});

这是这种方法的关键。

每个可能的缺点:

第一种方法是纯dom遍历。我不一定对此有问题,但是每次你遍历 dom 并且 a$timeout用于等待渲染时,都会有人大喊“这不是 angular 的设计目的”。

--我猜第二种方法更“有角度”,但是指令$observe在属性上注册,并且页面上可能有400多个输入,我不知道这是否会影响性能。

所以我的问题是,有没有更好的方法来访问这些嵌套输入,既可以安抚有角度的神,又可以在浏览器上轻松使用?还是我的一种方法是更好的方法?还是我应该放弃并在 Python/Jinja2 中完成这一切;)?

4

1 回答 1

0

我认为更让浏览器/用户满意的方法是使用 tabindex 属性。您可以在每个输入元素上吐出此属性,并使用 $index 值来获取 ng-repeat 所在的迭代次数。许多浏览器和移动设备连接到此属性以提供通过表单和列表的导航(例如,当关注表单输入时,iOS 中的前进/后退箭头)

另一种解决方案是使用指令每个元素

<input focus-this="{{$index}}"></input>

然后

directives.directive('focusThis', function(){
    return {
        link: function (scope, element, attrs){
            scope.$watch('focusedIndex', function(newVal, oldVal){
                if (newVal == attrs['focus-this']){
                    element.focus();
                }
                else {
                    element.blur();
                }
            });
        }
    };
});

您应该能够使用 keydown 事件更改focusedIndex 以转到上一个/下一个,甚至可以根据需要跳转到特定索引。

警告:未经测试的代码。只是一个概念。可能需要调整。

于 2013-07-08T15:39:51.780 回答